Java学习笔记3-线程通信
wait/notify:要求在同步关键字内使用,wait可以自动释放锁,免去了死锁的困扰,但是有顺序要求,一定要先调用wait,再调用notify,否则永久等待
park/unpark:没有顺序要求,但是park并不会释放锁,所以在同步代码中使用要注意
伪唤醒:线程并非notify、notifyall、unpark等api调用而唤醒,是更底层原因导致的。所以官方建议应该在循环中检查等待条件,用while(等待条件) 而非if(等待条件)
wait/notify测试代码
/**
* @Author: Wenx
* @Description:
* @Date: Created in 2019/11/7 19:35
* @Modified By:
*/
public class DemoTest {
public static Object lock = new Object();
public static Object baozi = null;
public static void main(String[] args) throws InterruptedException {
// 启动线程
new Thread(() -> {
synchronized (lock) {
while (baozi == null) { // 如果没包子,则进入等待
try {
System.out.println("没包子,坐等");
lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
System.out.println("买到包子,走人");
}).start();
// 2秒之后,做了个包子
Thread.sleep(2000L);
baozi = new Object();
synchronized (lock) {
lock.notifyAll();
System.out.println("包子出锅了");
}
}
}
park/unpark测试代码
/**
* @Author: Wenx
* @Description:
* @Date: Created in 2019/11/7 19:35
* @Modified By:
*/
public class DemoTest {
public static Object baozi = null;
public static void main(String[] args) throws InterruptedException {
// 启动线程
Thread t1 = new Thread(() -> {
while (baozi == null) { // 如果没包子,则进入等待
System.out.println("没包子,坐等");
LockSupport.park();
}
System.out.println("买到包子,走人");
});
t1.start();
// 2秒之后,做了个包子
Thread.sleep(2000L);
baozi = new Object();
LockSupport.unpark(t1);
System.out.println("包子出锅了");
}
}