知识卡片
等待条件必须循环复查
内容
调用 wait() 判断等待条件必须用 while 循环反复复查,不能用 if 只判断一次。线程被 notify 唤醒后只是重新获得竞争锁的资格,不保证条件依然成立——多个等待线程可能被同一次通知唤醒去抢同一份资源(竞争唤醒),if 只判断一次会带着过期条件继续执行。这是 [[生产消费靠条件]] 能正确工作的前提,是等待-通知模式正确性的核心,不是可选写法。
参考来源
- 位置:《Java高并发核心编程.卷2,多线程、锁、JMM、JUC、高并发设计模式》第2章《Java内置锁的核心原理》2.9.6节《需要在synchronized同步块的内部使用wait和notify》(源文件:_epub-src/OEBPS/Text/chapter95.xhtml)
- 结论依据:原文明确对比 while 与 if 两种写法,指出“调用wait()方法时使用while进行条件判断……不能使用if语句做一次性判断,而是使用while循环进行反复判断。只有这样才能在线程被唤醒后继续检查wait的条件,并在条件没有满足的情况下继续等待”,并各给出一段正确(while)和一段错误(if)的示例代码,因此可以推出本卡结论。
- 原始内容:调用wait()方法时使用while进行条件判断,如果是在某种条件下进行等待,对条件的判断就不能使用if语句做一次性判断,而是使用while循环进行反复判断。只有这样才能在线程被唤醒后继续检查wait的条件,并在条件没有满足的情况下继续等待。