介绍
两个特性:队列,阻塞。底层存储数据结构:链表。这里,我们通过put方法的实现,聊聊阻塞的实现。
put
public void put(E e) throws InterruptedException {
if (e == null) throw new NullPointerException();
int c = -1;
Node<E> node = new Node<E>(e);
// 这里我们可以产生了一个强烈的疑问:为什么还要临时变量指向锁和count
final ReentrantLock putLock = this.putLock;
final AtomicInteger count = this.count;
// 这里有个细节,为什么要使用lockInterruptibly
putLock.lockInterruptibly();
try {
// 已满,通过Condition阻塞
while (count.get() == capacity) {
notFull.await();
}
enqueue(node);
c = count.getAndIncrement();
if (c + 1 < capacity)
//每次入队操作完成,Condition通知阻塞等待的
notFull.signal();
} finally {
putLock.unlock();
}
// 这里,当一次入队完成,c==0(c是count返回pre的值,自增后其实是1)时,通知可以继续进行阻塞的take删除操作了
if (c == 0)
signalNotEmpty();
}
第一个问题: www.zhihu.com/question/28… 但个人还是很有疑问,这个问题暂且放着吧
最后,想突出的一点就是LinkedBlockingQueue是通过ReetrantLock和Condition的使用。ReetarntLock