gpt4 book ai didi

java - BlockingQueue 中的 take() 和 put() 实现

转载 作者:行者123 更新时间:2023-11-30 03:32:41 24 4
gpt4 key购买 nike

我了解BlockingQueue的理论和概念,但是当我查看implementation时对于 LinkedBlockingQueue。我不明白为什么我们使用 while 循环继续尝试并在 take() 方法的第 8 行等待(与 put() 相同>)。我认为 if 检查就足够了,因为从 put() 调用的 signalNotEmpty() 仅在第 27 行发出信号,但没有发出信号所有,所以只有一个等待线程会被唤醒,对吧?我想知道我错过了什么吗?有人可以解释一下为什么我们使用 while 而不是 if

这是代码片段

 1 public E take() throws InterruptedException {
2 E x;
3 int c = -1;
4 final AtomicInteger count = this.count;
5 final ReentrantLock takeLock = this.takeLock;
6 takeLock.lockInterruptibly();
7 try {
8 while (count.get() == 0) {
9 notEmpty.await();
10 }
11 x = dequeue();
12 c = count.getAndDecrement();
13 if (c > 1)
14 notEmpty.signal();
15 } finally {
16 takeLock.unlock();
17 }
18 if (c == capacity)
19 signalNotFull();
20 return x;
21 }
22
23 private void signalNotEmpty() {
24 final ReentrantLock takeLock = this.takeLock;
25 takeLock.lock();
26 try {
27 notEmpty.signal();
28 } finally {
29 takeLock.unlock();
30 }
31 }

如果我们将第 8 行更改为

会发生什么
if(count.get() == 0) { 
notEmpty.await();
}

最佳答案

这是因为虚假唤醒。请阅读条件类的javadoc另请参阅 Do spurious wakeups actually happen?

* <h3>Implementation Considerations</h3>
*
* <p>When waiting upon a {@code Condition}, a &quot;<em>spurious
* wakeup</em>&quot; is permitted to occur, in
* general, as a concession to the underlying platform semantics.
* This has little practical impact on most application programs as a
* {@code Condition} should always be waited upon in a loop, testing
* the state predicate that is being waited for. An implementation is
* free to remove the possibility of spurious wakeups but it is
* recommended that applications programmers always assume that they can
* occur and so always wait in a loop.

关于java - BlockingQueue 中的 take() 和 put() 实现,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28655173/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com