Java LinkedBlockingQueue的实现

Java LinkedBlockingQueue的实现,java,collections,Java,Collections,我查看了JDKLinkedBlockingQueue类,结果丢失了 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 fai

我查看了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();
}
public void put(E)抛出InterruptedException{
如果(e==null)抛出新的NullPointerException();
//注:所有put/take/etc中的惯例是预设本地var
//除非设置,否则保持计数为负数表示失败。
int c=-1;
final ReentrantLock putLock=this.putLock;
最终原子整数计数=this.count;
locklock.lockly();
试一试{
/*
*注意,count在wait-guard中使用,即使它是
*不受锁保护。这是因为计数可以
*仅在此点减少(所有其他PUT均关闭
*我们(或其他等待着的人)是
*如果它从
*容量。与计数的所有其他用途类似
*其他警卫。
*/
而(count.get()=容量){
未满。等待();
}
排队(e);
c=count.getAndIncrement();
如果(c+1<容量)
notFull.signal();
}最后{
putLock.unlock();
}
如果(c==0)
signalNotEmpty();
}
请看最后一个条件
(c==0)
,我认为应该是
(c!=0)

谢谢你,我明白了。 但我还有一个关于LinkedBlockingQueue实现的问题。
入队和出队函数不能相交。我看到执行put()时,take()也可以执行。而且头和尾对象没有同步,因此排队和出列可以在不同的线程中同时工作。它不是线程安全的,可能会发生故障。

c
是增量之前的
计数:

c = count.getAndIncrement();

因此,此条件表示“如果队列为空,则通知其他人它现在不为空”。

否,其目的是仅在队列从0变为1时发出信号(即首次向空队列添加内容)。将项目添加到已包含项目的队列时,不需要“发出非空信号”。(您会注意到,notEmpty条件仅在队列计数=0时才处于等待状态)。

您不需要在每个put上发出信号。即,如果检查是
c!=0
然后每次你放东西时,你都会发出信号说你不是空的,但如果你以前不是空的,就没有人可以发出信号。因此
c==0
确保您仅在队列从空状态更改为非空状态时发出信号

比较是c==0,而不是c==1,因为对count的调用是“getAndIncrement”,所以将返回0,然后count将递增


编辑:显然有人在我之前就知道了:\

c=count.getAndIncrement();是,如果队列为空,则c为1,而不是0。@itun-no,“getAndIncrement”表示“获取当前值(用于返回)并增加存储值”。因此,当队列为空时,c==0。至于edit:while(count.get()==0)notEmpty.await(),您可能错过了
在Take中,如果你有新问题,请问一个新问题——当现有问题被更改时,这真的很混乱。