LinkedBlockingQueue

194 阅读1分钟

介绍

两个特性:队列,阻塞。底层存储数据结构:链表。这里,我们通过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