通信的方式 wait/notify
# 线程协作通信的方式 wait/notify、park/unpark
![图片.png](https://cos.easydoc.net/31477061/files/klz4y7tg.png)
## wait/notify
![图片.png](https://cos.easydoc.net/31477061/files/klz8x451.png)
```
public static Object baozi=null;// 包子
public static String obj="suo"; //锁
/** 正常的wait/notify */
public static void waitNotifyTest() throws Exception {
new Thread(() -> {
while(baozi == null) { // 如果没,则进入等待
synchronized (obj) { // 加锁
try {
System.out.println("1.没有包子、进入等待");
obj.wait(); //释放当前的锁,然后让出CPU,进入等待状态。
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
System.out.println("2、买到包子,回家");
}).start();
// 3秒之后,生产一个包子
Thread.sleep(3000L);
baozi = new Object();
synchronized (obj) {
obj.notifyAll();
System.out.println("3、通知消费者");
}
}
```
==wait/notify==
要求在同步关键字里面使用,不会死锁。但要先调用wait在调用notify,否则永久等待。
## park/unpark
![image.png](https://cos.easydoc.net/31477061/files/km1cz8oo.png)
```
package smm.test.app.multiplesystems.lifter1;
import java.util.concurrent.locks.LockSupport;
public class test {
public static void main(String[] args) {
try {
parkUnparkTest();
} catch (Exception e) {
e.printStackTrace();
}
}
public static Object baozi=null;
/** 正常的park/unpark */
public static void parkUnparkTest() throws Exception {
// 启动线程
Thread consumerThread = new Thread(() -> {
while(baozi == null) { // 如果没包子,则进入等待
System.out.println("1、进入等待");
LockSupport.park();
}
System.out.println("2、买到包子,回家");
});
consumerThread.start();
// 3秒之后,生产一个包子
Thread.sleep(3000L);
baozi = new Object();
LockSupport.unpark(consumerThread);
System.out.println("3、通知消费者");
}
}
```
==park/unpark==
没有顺序要求,但是park并不会释放锁,在同步代码中使用会造成死锁。
## 伪唤醒
![image.png](https://cos.easydoc.net/31477061/files/km1epuba.png)
1.先加锁在挂起,2,先唤醒在挂起
![image.png](https://cos.easydoc.net/31477061/files/kmbjezry.png)