5.玩明白wait-notify-notifyAll方法
创始人
2024-02-12 03:45:19
0

今天总结一下wait-notify-notifyAll 方法,到底该怎么玩。

1.wait、 notify、 notifyAll

在使用 wait 方法时,必须把 wait 方法写在 synchronized 保护的 while 代码块中,并始终判断执行条件是否满足,如果满足就往下继续执行,如果不满足就执行 wait 方法,而在执行 wait 方法之前,必须先持有对象的 monitor 锁,也就是通常所说的 synchronized 锁。

为什么这么玩呢?

如果不要求 wait 方法放在 synchronized 保护的同步代码中使用,而是可以随意调用,会发生什么呢?

首先会造成线程不安全的情况。这个网站上有很多案例 可以自己去搜索。

所以我们在写代码的时候要这样写:

这样就可以确保 notify 方法永远不会在 buffer.isEmpty 和 wait 方法之间被调用,提升了程序的安全性。

//被 synchronized 保护的同步代码
public void notifyTest(String data) {synchronized (this) {buffer.add(data);notify();}
}
//被 synchronized 保护的同步代码
public String waitTest() throws InterruptedException {synchronized (this) {while (buffer.isEmpty()) {wait();}return buffer.remove();}
}

小知识【虚假唤醒】:

“虚假唤醒”(spurious wakeup)的问题,线程可能在既没有被notify/notifyAll,也没有被中断或者超时的情况下被唤醒。
虽然在实际生产中,虚假唤醒发生的概率很小,但是程序依然需要保证在发生虚假唤醒的时候的正确性,所以就需要采用while循环的结构。
这样即便被虚假唤醒了,也会再次检查while里面的条件,如果不满足条件,就会继续wait,也就消除了虚假唤醒的风险。

2.wait/notify 和 sleep 方法的区别

相同点:

  • 它们都可以让线程阻塞。
  • 它们都可以响应 interrupt 中断:在等待的过程中如果收到中断信号,都可以进行响应,并抛出 InterruptedException 异常。

不同点:

  • wait 方法必须在 synchronized 保护的代码中使用,而 sleep 方法并没有这个要求。
  • 在同步代码中执行 sleep 方法时,并不会释放 monitor 锁,但执行 wait 方法时会主动释放 monitor 锁。
  • sleep 方法中会要求必须定义一个时间,时间到期后会主动恢复,而对于没有参数的 wait 方法而言,意味着永久等待,直到被中断或被唤醒才能恢复,它并不会主动恢复。
  • wait/notify 是 Object 类的方法,而 sleep 是 Thread 类的方法。

相关内容

热门资讯

世俱杯|穆西亚拉断腿,大巴黎、... 转自:扬子晚报北京时间6日凌晨,世俱杯结束1/4决赛第2比赛日的争夺,随着大巴黎2:0战胜拜仁、皇马...
百宏实业7月4日斥资292.5... .ct_hqimg {margin: 10px 0;} .hqimg_wrapper {text-a...
马斯克回应对特朗普“由爱转恨”... 宣布成立“美国党”后,马斯克回应对特朗普“由爱转恨”原因美国亿万富翁埃隆·马斯克当地时间5日在社交媒...
能源巨构崛起渤海湾 转自:唐山发布能源巨构崛起渤海湾——探访唐山港煤炭储运配套翻车机房建设现场唐山劳动日报记者 景立华 ...
2025年暑期档票房破25亿元 转自:证券时报人民财讯7月6日电,据猫眼专业版数据,截至7月6日12时38分,2025年暑期档总票房...
40℃+!湖北多地连发高温预警 湖北省气象台高温橙色省级预警生效中。7月6日白天,除西部高山地区外,我省大部地区最高气温将升至37℃...
又一只,超2000元! 转自:扬子晚报扬子晚报网7月6日讯(记者 范晓林 薄云峰)7月3日,惠城转债在正股惠城环保冲高带动下...
城事·战高温 | 上海:高温“... 2025年7月6日,上海中心气象台8时45分发布高温黄色预警信号:预计今天本市大部地区的最高气温将超...
外媒爆料“以色列未公开5处军事... 【环球网报道】据英国《每日电讯报》5日报道,该媒体看到的数据显示,以色列与伊朗之间爆发冲突后,伊朗导...
上海电气7月4日斥资1095.... .ct_hqimg {margin: 10px 0;} .hqimg_wrapper {text-a...