2
回答
java多线程使用条件对象的时候,为什么建议用while来判断?
极速云服务器,低至1.04元/天>>>   

在看java核心技术讲到多线程中用条件对象,说到通常对await的调用应该在

while(!(ok to proceed))
{
condition.await();
}



我奇怪为什么推荐使用while来判断,可不可以用if

在代码中实验了下,在调用await()之前打印一下"thread will wait",发现用while时会打印大量的"thread will wait",而if时会少很多。这样是不是表示while和if的机制会不一样。想知道这是为什么推荐用while,它和if有啥区别

举报
Mr_Sky
发帖于3年前 2回/1K+阅
共有2个答案 最后回答: 3年前
因为可能有多个线程await在这里,一个notifyAll,全部唤醒,又要重新竞争,先得到时间片的线程向下运行了,其他线程又需要回到await上。如果不是while,而是if,所有的线程都会走下去了
--- 共有 2 条评论 ---
逝水fox回复 @Mr_Sky : 被线程被唤醒到获得时间片之间,条件有可能变 3年前 回复
Mr_Sky是不是就是指,在获得时间片以后,要重新做一次判断,所以用while 3年前 回复

举个例子,一个生产者消费者模型的任务队列,一个生产者一次可能放入多个任务,然后用notifyAll通知消费者,但是并非所有被唤醒的消费者都能取到一个任务,那么队列被读空了之后的消费者肯定得继续await。如果你用if来判断,这个消费者第二次被notify的时候就不会再次判断!(ok to proceed)这个条件了,如果这个时候这个消费者又一次没抢到任务,但是代码还是往下执行了,轻则空指针异常,重了干出什么事情来都说不定了。

所以必须用while来检查!(ok to proceed),这样可以保证每次被唤醒都会检查一次条件。

--- 共有 3 条评论 ---
Mr_Sky回复 @Maxwell1987 : 明白了,感谢 3年前 回复
Maxwell1987回复 @Mr_Sky : 是的,所以它醒了之后你得用while循环让它再去判断一次条件。 3年前 回复
Mr_Sky谢谢。线程唤醒以后,是从condition.await(); 后面的代码开始执行对吗? 3年前 回复
顶部