我看了看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实现的问题。入队和出队函数不能相交。我看到当put()被执行时,take()也可以被执行。并且头部和尾部对象不具有同步性,因此入队和出队可以在不同的线程中同时进行。它不是线程安全的,可能会发生故障。
发布于 2011-03-30 04:42:15
不,其目的是仅在队列从0变为1时发出信号(即首次向空队列添加某些内容)。在向已有项的队列中添加项时,不需要"signal not empty“。(您会注意到,只有当队列计数==为0时,才会等待notEmpty条件)。
发布于 2011-03-30 04:46:33
你不需要在每一个put上都发信号。也就是说,如果检查是c != 0,那么每次你放入一些东西时,你都会发出信号表明你不是空的,但如果你之前不是空的,就没有人会发信号了。因此,c == 0确保您仅在队列将从空状态更改为非空状态时发出信号。
比较结果是c == 0,而不是c == 1,因为对count的调用是一个"getAndIncrement“,所以将返回0,然后count将递增。
编辑:显然有人已经在我之前找到了这个:\
发布于 2011-03-30 04:10:34
c是增量前的count:
c = count.getAndIncrement();因此,这个条件意味着“如果queue是空的,就通知其他人它现在不是空的”。
https://stackoverflow.com/questions/5478284
复制相似问题