LinkedBlockingQueue

單同志發表於2019-08-16

介紹

兩個特性:佇列,阻塞。底層儲存資料結構:連結串列。這裡,我們通過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