gpt4 book ai didi

java - 关于 LinkedBlockingQueue 源代码的一些困惑

转载 作者:行者123 更新时间:2023-11-30 10:17:51 26 4
gpt4 key购买 nike

在 LinkedBlockingQueue 的源码中

public void put(E e) throws InterruptedException {
if (e == null) throw new NullPointerException();
// Note: convention in all put/take/etc is to preset local var
// holding count negative to indicate failure unless set.
int c = -1;
Node<E> node = new Node<E>(e);
final ReentrantLock putLock = this.putLock;
final AtomicInteger count = this.count;
putLock.lockInterruptibly();
try {
/*
* Note that count is used in wait guard even though it is
* not protected by lock. This works because count can
* only decrease at this point (all other puts are shut
* out by lock), and we (or some other waiting put) are
* signalled if it ever changes from capacity. Similarly
* for all other uses of count in other wait guards.
*/
while (count.get() == capacity) {
notFull.await();
}
enqueue(node);
c = count.getAndIncrement();
// #Question 1
if (c + 1 < capacity)
notFull.signal();
} finally {
putLock.unlock();
}
if (c == 0)
signalNotEmpty();
}

我有两个问题:

1 #Question 1 在什么情况下会发生?为什么我们在将一个对象放入队列后在 put 方法中调用 notFull.signal()。

2 为什么 signalNotEmpty 应该在 notEmpty.signal() 之前锁定 takeLock

 private void signalNotEmpty() {
final ReentrantLock takeLock = this.takeLock;
takeLock.lock();
try {
notEmpty.signal();
} finally {
takeLock.unlock();
}
}

最佳答案

1) 如果队列已满,则条件为 true。如果我理解正确的话,notFull.signal() 调用在 LinkedBlockingQueue 的当前实现中并不是真正必要的。由于所有锁和条件都是私有(private)的,因此派生类也不会从调用中受益。所以我想它只是为了确保 future 对该类的扩展的正确性。

2) 获取 takeLock 是必要的,以防止其他线程在 notEmpty 发出信号时清空队列。

关于java - 关于 LinkedBlockingQueue 源代码的一些困惑,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49557939/

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