java - 求对ArrayBlockingQueue中一段源码的解释
本文介绍了java - 求对ArrayBlockingQueue中一段源码的解释的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
问 题
为什么take()方法在判断队列中元素个数是否为0的时候使用了while循环,而不是if;
我认为,如果notEmpty.await()方法既然苏醒返回了 ,那么此线程肯定拿到了lock。
而苏醒的原因也是因为put()方法放入了新的元素,而其他线程无法拿到锁,自然无法取走元素,那么此时对于拿到锁的线程来说count肯定不为0了,应该放心的执行 dequeue()获取元素就可以了。
不知道作者使用了while是何意呢?
解决方案
notEmpty.await()方法既然苏醒返回了 ,那么此线程肯定拿到了 lock 这句话是正确的。
假设你写的代码是:
if (count == 0)
notEmpty.await();
可以明确的一点就是我们需要保证在 return dequeue()
之前需要满足的一个条件是 count != 0
。我们假设 线程A 此时拿到了 lock,那么 线程A 的 notEmpty.await()
此时便会停止阻塞,准备向下执行 return dequeue()
。但是假设在竞争激烈的条件下,线程A 拿到 lock 之后,准备执行下一条 JVM 指令的时候,线程B 此时抢占了 lock,然后继续向下执行 return dequeue()
,刚好使得 count 变为了 0;而此时因为写的只是 if(count == 0)
,那么线程 A 在拿到 lock 之后,还是会继续向下执行 return dequeue()
,从而导致了错误。
关于为什么wait()
、await()
这样当条件不满足时就阻塞的方法一定要在 while 循环中使用,可以参考《Effective Java》第二版第 69 条(244 页)。
这篇关于java - 求对ArrayBlockingQueue中一段源码的解释的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!
查看全文