1.背景
一个线程修改了一个对象的值,而另一个线程感知到了变化,然后进行相应的操作,整个
过程开始于一个线程,而最终执行又是另一个线程。
2. 解决方案
2.1 轮询方式
让消费者线程不断地循环检查变量是否符合预期
// 伪代码
while(value != desire) {
Thread.sleep(1000);
}
doSomething();
2.2 等待通知范式
利用Object上的wait()和notify()方法进行线程间的交互
// A线程
synchronized(对象){
while(条件不满足){
对象.wait();
}
对应的处理逻辑
}
// B线程
synchronized(对象){
改变条件
对象.notifyAll();
}
2.3 优缺点对比
轮询方式不仅消耗CPU,而且没有及时性.
3.实现
public class NotifyWait {
static Object lock = new Object();
static volatile boolean flag = true;
public static void main(String[] args) throws InterruptedException {
Thread waitThread = new Thread(new Wait(), "WaitThread");
waitThread.start();
TimeUnit.SECONDS.sleep(1);
Thread notifyThread = new Thread(new Notify(), "NotifyThread");
notifyThread.start();
}
static class Wait implements Runnable {
@Override
public void run() {
synchronized (lock) {
while (flag) {
try {
System.out.println("准备下好好工作了");
System.out.println("WAIT,我快要进入等待队列了,好难受呀");
lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("终于能好好工作了");
}
}
}
static class Notify implements Runnable {
@Override
public void run() {
synchronized (lock) {
flag = false;
System.out.println("NOTIFY,我要脱离等待队列了,好高兴呀");
lock.notifyAll();
}
}
}
}
执行结果
准备下好好工作了
WAIT,我快要进入等待队列了,好难受呀
NOTIFY,我要脱离等待队列了,好高兴呀
终于能好好工作了