代码演示
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(); }
注意:线程不能进行自我唤醒,必须由其它线程唤醒
