put源码
public void put(E e)throws InterruptedException {
if (e ==null)throw new NullPointerException();
int c = -1;
Node node =new Node(e);
final ReentrantLock putLock =this.putLock;
final AtomicInteger count =this.count;
putLock.lockInterruptibly();
try {
while (count.get() ==capacity) {
notFull.await();
}
enqueue(node);
c = count.getAndIncrement();
if (c + 1 < capacity)
notFull.signal();
}finally {
putLock.unlock();
}
if (c ==0)
signalNotEmpty();
}
LinkedBlockingQueue的put为什么是if(c==0) signalNotEmpty()?
按理来说,put完之后应该是直接signalNotEmpty的才对,为什么还要判断c==0?
首先,c的有用赋值是c = count.getAndIncrement();,注意这里的getAndIncrement。比如count是1的话,c是等于1的。
所以这里的if(c==0),意思就是,在put之前,这个LinkedBlockingQueue是空的,队列里面是没有值。
如果之前的队列本身不为空,则说明没有处于因notEmpty.wait(),反之,如果count为空,则有可能有线程处于notEmpty.wait()。(比如,这个队列是空的,先take后put,take方法里面如果count等于0是会notEmpty.await的)
注意,因为不管是take还是put,都是使用独占锁,意思是只有一个线程在处于notEmpty.wait(),其他都会在lock那里等待。所以,只需要 c是0的时候(有且只能有一个线程卡在notEmpty.wait()),才需要signal唤醒。同理,take方法也一样(处理 队列满了先put后take的问题)。以上。