斐讯面试记录—三线程交替打印ABC
2024-09-04 09:44:01
package cn.shenzhen.feixun; public class PrintABC extends Thread{
private String name;
private Object prev;
private Object self; public PrintABC(String name,Object prev,Object self){
this.name=name;
this.prev=prev;
this.self=self;
}
/**
* ,为了控制执行的顺序,必须要先持有prev锁,
* 也就是前一个线程要释放自身对象锁,再去申请自身对象锁,两者兼备时打印字母,
* 之后首先调用self.notify()释放自身对象锁,唤醒下一个等待线程,
* 再调用prev.wait()释放prev对象锁,终止当前线程,等待循环结束后再次被唤醒。
* 程序运行的主要过程就是A线程最先运行,持有C,A对象锁,后释放A,C锁,唤醒B。
* 线程B等待A锁,再申请B锁,后打印B,再释放B,A锁,唤醒C,线程C等待B锁,再申请C锁,
* 后打印C,再释放C,B锁,唤醒A……
*/
public void run(){
int count=0;
while(count<10){
// 先获取 prev锁 如此问题中先将对象C锁住
synchronized (prev) {
//然后获取自身的锁如此问题中将对象A锁住
synchronized (self) {
System.out.print(name+"");
count++;
self.notify();//此问题中一共有三个对象ABC此时将self唤醒,是其他线程来竞争self
}
try {
prev.wait();
/**
* 注意的是notify()调用后,并不是马上就释放对象锁,
* 而是在相应的synchronized(){}语句块执行结束,自动释放锁,
* JVM会在wait()对象锁的线程中随机选取一线程,赋予其对象锁,唤醒线程,继续执行。
*/
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public static void main(String[] args) throws InterruptedException {
Object a=new Object();
Object b=new Object();
Object c=new Object(); PrintABC printA=new PrintABC("A", c, a);//第一个线程先将AC对象锁住,A执行完了之后释放锁
PrintABC printB=new PrintABC("B", a, b);
PrintABC printC=new PrintABC("C", b, c); /**
* 为了避免JVM启动ThreadA、ThreadB、ThreadC三个线程顺序的不确定性。
* 需要让A,B,C三个线程以确定的顺序启动,中间加一段sleep确保前一个线程已启动。
*/
printA.start();
/**
* sleep()方法导致了当前线程暂停执行指定的时间,
* 让出cpu该其他线程,但是他的监控状态依然保持者,
* 当指定的时间到了又会自动恢复运行状态。
*/
printA.sleep(10);
printB.start();
printB.sleep(10);
printC.start();
printC.sleep(10);
}
}
最新文章
- 【WPF】WPF中调用Winform
- 【CITE】DrawImage方法详解(转)
- FileReader 基本介绍
- Msp430概述
- HTML - Textarea - 空格的问题解决方式
- log4net使用简介
- java 接口与实现
- Spring @Transactional使用的示例
- 《Java技术》第三次作业--面向对象——继承、抽象类、接口
- gradle.properties使用
- A.01.11—模块的输出—输出复用和可配
- linux中bashrc与profile的区别
- vue里碰到 $refs 的问题
- Spring Cloud (6)A config 服务端配置 与github通信
- syslog、日志服务器安装、卸载详解、如何安装和卸载EventLog Analyzer
- 通过 NewLife.XCode 迁移任意现有数据库到任意数据库
- Azkaban上传出错
- js 的each()方法遍历对象和数组
- 常用Build-in Keywords
- CentOS下NTP安装配置
热门文章
- 【代码备份】NLM插值
- ArcGIS GP应用-GP模型服务发布
- Android自定义控件之圆形进度条ImageView
- Java调用http保留访问状态
- Python全栈day21-22-23(模块)
- linux, sysrq,acpi,apci,uio,subsystem daemon
- Python中的推导式(列表推导式、字典推导式、集合推导式)
- NFS服务基础
- Clairewd’s message--hdu4300(Next数组的运用)
- 为golang程序使用pprof远程查看httpserver运行堆栈,cpu耗时等信息