publicvoidput(E e)throws InterruptedException { if (e == null) thrownew 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); 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 增加之前的值 c = count.getAndIncrement(); // c+1代表当前的count,如果满足下面的条件 // 则表明当前队列还未满,所以调用 notFull.signal() // 同时 notFull 应该在获得 putLock 的时候被调用 // 所以这里在 释放 putLock 锁之前调用 if (c + 1 < capacity) notFull.signal(); } finally { putLock.unlock(); } // 如果 c == 0 ,则 通过上面的put,此时其时 count == 1 // 所以队列中就应该不是空的,所以可以通知 taker 线程,可以 // 从队列中取数据了。 if (c == 0) signalNotEmpty(); }