package com.company.java_thread_design.status; public class StatusChangeNotifyThread extends Thread{ private Object waitObject; private boolean flag; public Thread peer1; public Thread peer2; public StatusChangeNotifyThread(Object waitObject, boolean flag) { this.waitObject = waitObject; this.flag = flag; } public void setPeer1(Thread peer1) { this.peer1 = peer1; } public void setPeer2(Thread peer2) { this.peer2 = peer2; } public void setFlag(boolean flag) { this.flag = flag; } /** * https://blog.csdn.net/pange1991/article/details/53860651 */ @Override public void run() { try { synchronized (waitObject) { System.out.println("come in : "+this.getName()+" "+this.getState()+"\t"+peer1.getName()+" "+peer1.getState()+"\t"+peer2.getName()+" "+peer2.getState()); while (flag) { System.out.println("while first: "+this.getName()+" "+this.getState()+"\t"+peer1.getName()+" "+peer1.getState()+"\t"+peer2.getName()+" "+peer2.getState()); Thread.sleep(2000); waitObject.wait(); System.out.println("while second: "+this.getName()+" "+this.getState()+"\t"+peer1.getName()+" "+peer1.getState()+"\t"+peer2.getName()+" "+peer2.getState()); } System.out.println("after: "+this.getName()+" "+this.getState()); } } catch (InterruptedException e) { e.printStackTrace(); } } }
以上是线程类
package com.company.java_thread_design.status; import static com.company.java_thread_design.status.MainNotifyAll.sleep; public class Main { public static void main(String[] args) { Object waitObject = new Object(); boolean flag = true; Thread t0 = new StatusChangeNotifyThread(waitObject, flag); Thread t1 = new StatusChangeNotifyThread(waitObject, flag); Thread t2 = new StatusChangeNotifyThread(waitObject, flag); ((StatusChangeNotifyThread) t0).setPeer1(t1); ((StatusChangeNotifyThread) t0).setPeer2(t2); ((StatusChangeNotifyThread) t1).setPeer1(t0); ((StatusChangeNotifyThread) t1).setPeer2(t2); ((StatusChangeNotifyThread) t2).setPeer1(t0); ((StatusChangeNotifyThread) t2).setPeer2(t1); System.out.println("\n====== > start first Thread"); t0.start(); sleep(3000); printThreadStatus(t0, t1,t2); System.out.println("\n====== > start second Thread"); t1.start(); sleep(3000); printThreadStatus(t0, t1,t2); System.out.println("\n====== > start third Thread"); t2.start(); sleep(3000); printThreadStatus(t0, t1,t2); /** * 三个线程都是waiting状态 */ synchronized (waitObject) { System.out.println("\n\n\n====== > notify first thread"); waitObject.notify(); } printThreadStatus(t0, t1,t2); sleep(10000); // flag = false; // ((StatusChangeNotifyThread) t0).setFlag(flag); // ((StatusChangeNotifyThread) t1).setFlag(flag); // ((StatusChangeNotifyThread) t2).setFlag(flag); synchronized (waitObject) { System.out.println("\n====== > notify second thread"); waitObject.notify(); } printThreadStatus(t0, t1,t2); /** * 两个被唤醒,一个还是waiting */ sleep(10000); System.out.println("t0: "+t0.getState()); System.out.println("t1: "+t1.getState()); System.out.println("t2: "+t2.getState()); sleep(1000); } public static void sleep(int mill) { try { Thread.sleep(mill); } catch (InterruptedException e) { e.printStackTrace(); } } public static void printThreadStatus(Thread t0, Thread t1, Thread t2) { System.out.println("###### -- >> "+t0.getName()+" "+t0.getState()+"\t"+t1.getName()+" "+t1.getState()+"\t"+t2.getName()+" "+t2.getState()); } /** * ====== > start first Thread * come in : Thread-0 RUNNABLE Thread-1 NEW Thread-2 NEW * while : Thread-0 RUNNABLE Thread-1 NEW Thread-2 NEW * ###### -- >> Thread-0 WAITING Thread-1 NEW Thread-2 NEW * * ====== > start second Thread * come in : Thread-1 RUNNABLE Thread-0 WAITING Thread-2 NEW * while : Thread-1 RUNNABLE Thread-0 WAITING Thread-2 NEW * ###### -- >> Thread-0 WAITING Thread-1 WAITING Thread-2 NEW * * ====== > start third Thread * come in : Thread-2 RUNNABLE Thread-0 WAITING Thread-1 WAITING * while : Thread-2 RUNNABLE Thread-0 WAITING Thread-1 WAITING * ###### -- >> Thread-0 WAITING Thread-1 WAITING Thread-2 WAITING * 注解:上面是三个线程启动 * * * ====== > notify first thread * ###### -- >> Thread-0 BLOCKED Thread-1 WAITING Thread-2 WAITING * while : Thread-0 RUNNABLE Thread-1 WAITING Thread-2 WAITING * 注解:唤醒一个(thread-0)刚notify时候还没释放锁,所以为blocked,后来重新获得锁,runnable,并又一次判断condition * * ====== > notify second thread * ###### -- >> Thread-0 WAITING Thread-1 BLOCKED Thread-2 WAITING * while : Thread-1 RUNNABLE Thread-0 WAITING Thread-2 WAITING * 和上一次类似 * * t0: WAITING * t1: WAITING * t2: WAITING */ }
package com.company.java_thread_design.status; public class MainNotifyAll { public static void main(String[] args) { Object waitObject = new Object(); boolean flag = true; Thread t0 = new StatusChangeNotifyThread(waitObject, flag); Thread t1 = new StatusChangeNotifyThread(waitObject, flag); Thread t2 = new StatusChangeNotifyThread(waitObject, flag); ((StatusChangeNotifyThread) t0).setPeer1(t1); ((StatusChangeNotifyThread) t0).setPeer2(t2); ((StatusChangeNotifyThread) t1).setPeer1(t0); ((StatusChangeNotifyThread) t1).setPeer2(t2); ((StatusChangeNotifyThread) t2).setPeer1(t0); ((StatusChangeNotifyThread) t2).setPeer2(t1); System.out.println("\n====== > start first Thread"); t0.start(); sleep(3000); printThreadStatus(t0, t1,t2); System.out.println("\n====== > start second Thread"); t1.start(); sleep(3000); printThreadStatus(t0, t1,t2); System.out.println("\n====== > start third Thread"); t2.start(); sleep(3000); printThreadStatus(t0, t1,t2); /** * 三个线程都是waiting状态 */ synchronized (waitObject) { System.out.println("\n\n\n====== > notify first thread"); waitObject.notifyAll(); } printThreadStatus(t0, t1,t2); // flag = false; // ((StatusChangeNotifyThread) t0).setFlag(flag); // ((StatusChangeNotifyThread) t1).setFlag(flag); // ((StatusChangeNotifyThread) t2).setFlag(flag); sleep(10000); synchronized (waitObject) { System.out.println("\n====== > notify second thread"); waitObject.notifyAll(); } printThreadStatus(t0, t1,t2); /** * 两个被唤醒,一个还是waiting */ sleep(10000); System.out.println("t0: "+t0.getState()); System.out.println("t1: "+t1.getState()); System.out.println("t2: "+t2.getState()); sleep(2000); } public static void sleep(int mill) { try { Thread.sleep(mill); } catch (InterruptedException e) { e.printStackTrace(); } } public static void printThreadStatus(Thread t0, Thread t1, Thread t2) { System.out.println("###### -- >> "+t0.getName()+" "+t0.getState()+"\t"+t1.getName()+" "+t1.getState()+"\t"+t2.getName()+" "+t2.getState()); } /** 这里的注释不太对(是在没有sleep的情况下,三个线程都block,然后排队依次获取锁,然后再wait的过程) * ====== > start first Thread * come in : Thread-0 RUNNABLE Thread-1 NEW Thread-2 NEW * while : Thread-0 RUNNABLE Thread-1 NEW Thread-2 NEW * ###### -- >> Thread-0 WAITING Thread-1 NEW Thread-2 NEW * * ====== > start second Thread * come in : Thread-1 RUNNABLE Thread-0 WAITING Thread-2 NEW * while : Thread-1 RUNNABLE Thread-0 WAITING Thread-2 NEW * ###### -- >> Thread-0 WAITING Thread-1 WAITING Thread-2 NEW * * ====== > start third Thread * come in : Thread-2 RUNNABLE Thread-0 WAITING Thread-1 WAITING * while : Thread-2 RUNNABLE Thread-0 WAITING Thread-1 WAITING * ###### -- >> Thread-0 WAITING Thread-1 WAITING Thread-2 WAITING * 注解:上面是三个线程启动 * * ====== > notify first thread ###### -- >> Thread-0 BLOCKED Thread-1 BLOCKED Thread-2 BLOCKED (刚notify,三个都没抢到,都是block) while : Thread-2 RUNNABLE Thread-0 BLOCKED Thread-1 BLOCKED while : Thread-1 RUNNABLE Thread-0 BLOCKED Thread-2 WAITING while : Thread-0 RUNNABLE Thread-1 WAITING Thread-2 WAITING 注解:这里唤醒了所有的waiting线程,刚开始主线程没有释放锁,所以都是block,然后2、1、0线程依次获得了锁,重新执行且只执行了condicion方法(不是从synchronize开始) ====== > notify second thread ###### -- >> Thread-0 BLOCKED Thread-1 BLOCKED Thread-2 BLOCKED while : Thread-0 RUNNABLE Thread-1 BLOCKED Thread-2 BLOCKED while : Thread-1 RUNNABLE Thread-0 WAITING Thread-2 BLOCKED while : Thread-2 RUNNABLE Thread-0 WAITING Thread-1 WAITING * 和上一次类似 * * t0: WAITING * t1: WAITING * t2: WAITING */ }
这张图是各种状态的转换过程,但是没有极短时间的线程切换过程,比如notify后还没有释放锁,被唤醒的应该是block,然后才是runnable,然后再是sleep、wait