我查看了JDK 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;
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(e);
c = count.getAndIncrement();
if (c + 1 < capacity)
notFull.signal();
} finally {
putLock.unlock();
}
if (c == 0)
signalNotEmpty();
}
请注意最后一个条件(c == 0)
,我认为它应该是(c != 0)
谢谢,我明白了。 但我还有一个关于LinkedBlockingQueue实现的问题。 enqueue和dequeue函数不能相交。我看到执行put()时,也可以执行take()。并且head和tail对象没有同步,而enqueue和dequeue可以在不同的线程中同时工作。它不是线程安全的,可能会发生故障。
答案 0 :(得分:3)
不,当队列从0变为1时(即第一次将某些内容添加到空队列中),目的是仅发送 。将项目添加到已包含项目的队列时,您不需要“发出非空信号”。 (您会注意到只有当队列计数== 0时才会等待notEmpty条件。)
答案 1 :(得分:1)
您不需要每次发出信号。即,如果支票是c != 0
,那么每次你放一些东西,你都会发出信号表明你不是空的,但是如果你之前没有空的话就没有人发出信号。因此c == 0
确保您仅在队列从空状态更改到非空状态时发出信号。
比较是c == 0,而不是c == 1,因为对count的调用是“getAndIncrement”,所以将返回0,然后count将递增。
编辑:显然有人已经在我面前这样做了:\
答案 2 :(得分:0)
c
是count
:
c = count.getAndIncrement();
所以,这个条件意味着“如果队列为空,请通知其他人现在它不是空的”。