进程通讯之wait/notify
wait():调用wait方法的线程释放当前的锁,并使当前线程处于等待状态。
notify():使用notify方法,使得用notify调用者对象作为Monitor的wait线程随机一个被唤醒。
notifyAll(): 使得用notifyAll()调用者对象作为Monitor的wait线程都被唤醒。
tip: 1. notifyAll()不是唤醒所有处于wait状态的线程,而是只唤醒使用当前调用notifyAll()对象作为Monitor的wait线程。
2. wait和notify的锁对象及调用方法的对象必须是同一个,即当前线程的Monitor对象,否则发生IllegalMonitorStateException
/**
* 进程通讯:wait notify
*/
public class WaitNotify {
/**
* 缓存WaitTarget任务的线程Monitor
*/
public static ConcurrentHashMap<String,Object> waitPool = new ConcurrentHashMap<>();
@Test
public void test() throws InterruptedException {
//创建等待任务
WaitTarget waitTarget = new WaitTarget();
//创建唤醒任务
NotifyTarget notifyTarget = new NotifyTarget();
//执行等待任务
waitTarget.execWait();
//执行唤醒任务
notifyTarget.execNotify();
try{
//主线程休眠等待
TimeUnit.DAYS.sleep(1);
}catch (Exception e){
}
}
/**
* 等待任务
*/
public class WaitTarget{
public void execWait(){
for (int i=0;i<10;i++){
//创建10个线程,每个线程创建一个Monitor,然后调用Monitor的wait()方法,使得当前线程处于等待状态。
new Thread(()->{
String key = UUID.randomUUID().toString();
Object monitor = new Object();
synchronized (monitor){
//将当前wait线程注册到等待池中,方便一会唤醒
WaitNotify.waitPool.put(key,monitor);
System.out.println(Thread.currentThread()+"正在等待,key="+key);
try {
monitor.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread()+"等待结束。。。。。。key="+key);
}
}).start();
}
}
}
/**
* 唤醒任务
*/
public class NotifyTarget{
public void execNotify() throws InterruptedException {
//休眠2秒 让所有WaitTarget中的所有wait线程处于wait状态
TimeUnit.SECONDS.sleep(2);
System.out.println("开始notify");
// WaitNotify.waitPool.forEach((k,v)->{
// System.out.println("=========唤醒"+k);
// synchronized (v){
// v.notify();
// }
// });
String key = WaitNotify.waitPool.keys().nextElement();
Object monitor = WaitNotify.waitPool.get(key);
synchronized (monitor){
System.out.println("key="+key+"被唤醒");
monitor.notifyAll();
}
}
}
}
执行结果如下:
可以看到,只有对应Monitor的wait线程被唤醒。即便是调用了notifyAll()方法,其他Monitor的wait线程同样还是处于wait状态。
如果线程在wait后没有释放锁,那么不可能进入notify代码段,因为使用的同一个Monitor对象作为锁,即同一把锁。
如果你觉得这篇内容对你还蛮有帮助,我想邀请你帮我三个小忙:
-
点赞,转发,有你们的 『点赞和评论』,才是我创造的动力。
-
关注公众号 『逆行的碎石机』,不定期分享原创知识。
-
同时可以期待后续文章ing🚀