等待/通知机制,是指一个线程A调用对象O的wait()方法进入等待状态,另一个线程B调用对象O的notify()或notifyAll()方法,线程A收到通知后从对象O的wait()方法返回.等待/通知机制用来完成等待方和通知方中间的交互工作.
/**
* @Auther: xieyuhui
* @Date: 2019-06-05 08:55
* @Description: 等待通知demo
*/
public class WaitNotify {
static boolean flag = true;
static Object lock = new Object();
public static void main(String[] args) throws Exception {
Thread waitThread = new Thread(new Wait(), "WaitThread");
Thread notifyThread = new Thread(new Notify(), "NotifyThread");
waitThread.start();
TimeUnit.SECONDS.sleep(1);
notifyThread.start();
}
static class Wait implements Runnable {
@Override
public void run() {
//加锁,持有lock 对象的Monitor
synchronized (lock) {
//条件不满足时,继续wait,同时释放锁
while (flag) {
try {
System.out.println(Thread.currentThread() + " flag is true,wait @ " +
new SimpleDateFormat("HH:mm;ss").format(new Date()));
lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
//条件满足时,完成工作
System.out.println(Thread.currentThread() + " flag is false, running @ " +
new SimpleDateFormat("HH:mm;ss").format(new Date()));
}
}
}
static class Notify implements Runnable {
@Override
public void run() {
synchronized (lock) {
try {
System.out.println(Thread.currentThread() + " hold lock, notify @ " +
new SimpleDateFormat("HH:mm;ss").format(new Date()));
lock.notify();
flag = false;
TimeUnit.SECONDS.sleep(5);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
synchronized (lock) {
System.out.println(Thread.currentThread() + " hold lock again, sleep @ " +
new SimpleDateFormat("HH:mm;ss").format(new Date()));
try {
TimeUnit.SECONDS.sleep(5);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
上面的代码示例可以提炼出等待/通知的经典范式
-
等待方
1.获取对象的锁
2.如果条件不满足,调用对象的wait()方法
3.条件满足则执行逻辑 -
通知方
1.获取对象的锁
2.改变条件
3.调用对象的notify()方法通知等待在该对象上的线程