代码演示
package com.dwz.concurrency2.chapter2; import java.util.stream.IntStream; /** * 1.所有的对象都会有一个wait set,用来存放调用了该对象wait方法之后进入block状态的线程 * 2.线程被notify之后,不一定立即得到执行 * 3.线程从wait set中被唤醒的顺序不一定是FIFO * 4.线程被唤醒后,必须重新去获取锁,会记录之前wait的位置,在wait的位置继续往下执行 */ public class WaitSet { private static final Object LOCK = new Object(); private static void work() { synchronized (LOCK) { System.out.println("begin..."); try { System.out.println("Thread will come in."); LOCK.wait(); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("Thread will out."); } }
}
测试一:验证线程从wait set中被唤醒的顺序不一定是FIFO
IntStream.rangeClosed(1, 10).forEach(i-> new Thread(String.valueOf(i)) { @Override public void run() { synchronized (LOCK) { try { System.out.println(Thread.currentThread().getName() + " will come to wait set."); LOCK.wait(); System.err.println(Thread.currentThread().getName() + " will leave to wait set."); } catch (InterruptedException e) { e.printStackTrace(); } } } }.start() ); Thread.sleep(3000); IntStream.rangeClosed(1, 10).forEach(i-> { synchronized (LOCK) { LOCK.notify(); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } } } );
测试二:验证线程被唤醒后,必须重新去获取锁,会记录之前wait的位置,在wait的位置继续往下执行
new Thread() { @Override public void run() { work(); } }.start(); try { Thread.sleep(3000); } catch (InterruptedException e) { e.printStackTrace(); } synchronized (LOCK) { LOCK.notifyAll(); }
注意:线程不能进行自我唤醒,必须由其它线程唤醒