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);
}
}

最新文章

  1. 【WPF】WPF中调用Winform
  2. 【CITE】DrawImage方法详解(转)
  3. FileReader 基本介绍
  4. Msp430概述
  5. HTML - Textarea - 空格的问题解决方式
  6. log4net使用简介
  7. java 接口与实现
  8. Spring @Transactional使用的示例
  9. 《Java技术》第三次作业--面向对象——继承、抽象类、接口
  10. gradle.properties使用
  11. A.01.11—模块的输出—输出复用和可配
  12. linux中bashrc与profile的区别
  13. vue里碰到 $refs 的问题
  14. Spring Cloud (6)A config 服务端配置 与github通信
  15. syslog、日志服务器安装、卸载详解、如何安装和卸载EventLog Analyzer
  16. 通过 NewLife.XCode 迁移任意现有数据库到任意数据库
  17. Azkaban上传出错
  18. js 的each()方法遍历对象和数组
  19. 常用Build-in Keywords
  20. CentOS下NTP安装配置

热门文章

  1. 【代码备份】NLM插值
  2. ArcGIS GP应用-GP模型服务发布
  3. Android自定义控件之圆形进度条ImageView
  4. Java调用http保留访问状态
  5. Python全栈day21-22-23(模块)
  6. linux, sysrq,acpi,apci,uio,subsystem daemon
  7. Python中的推导式(列表推导式、字典推导式、集合推导式)
  8. NFS服务基础
  9. Clairewd’s message--hdu4300(Next数组的运用)
  10. 为golang程序使用pprof远程查看httpserver运行堆栈,cpu耗时等信息