LinkedBlockingQueue中put原始碼分析

lonecloud發表於2018-04-29

檢視原始碼得知:

LinkedBlockingQueue採用是鎖分離的技術

    //取出鎖
    private final ReentrantLock takeLock = new ReentrantLock();

    //取出鎖條件
    private final Condition notEmpty = takeLock.newCondition();

    //插入鎖
    private final ReentrantLock putLock = new ReentrantLock();

    //插入鎖條件
    private final Condition notFull = putLock.newCondition();

檢視put方法原始碼

 public void put(E e) throws InterruptedException {
        //判斷元素為空
        if (e == null) throw new NullPointerException();
        //設定元素值
        int c = -1;
        //建立節點
        Node<E> node = new Node<E>(e);
        //獲取插入鎖
        final ReentrantLock putLock = this.putLock;
        //設定數量
        final AtomicInteger count = this.count;
        //嘗試加鎖
        putLock.lockInterruptibly();
        try {
            //判斷如果這個數量等於容器數量說明容器滿了
            while (count.get() == capacity) {
                //等待
                notFull.await();
            }
            //插入
            enqueue(node);
            //長度+1
            //這裡獲取的c應該是原本的資料,getAndIncrement相當於i++
            c = count.getAndIncrement();
            //判斷其+1後是否小於容器體積
            if (c + 1 < capacity)
                //小於則通知其他插入執行緒進行插入
                notFull.signal();
        } finally {
            //解鎖
            putLock.unlock();
        }
        //如果c==0表示本來沒有元素,現在已經有元素了
        //所以必須將其queue中的等待釋放
        if (c == 0)
            signalNotEmpty();
    }

  其中這句原始碼理解挺久的:為何要加入這句話呢?

if (c == 0)
            signalNotEmpty();

 由於c為獲取的是新增元素前的資料,判斷為0說明之前該佇列為空,導致take方法中的執行緒處於等待的狀態,通過該方法可以使得其take方法中的等待執行緒釋放,讓其可以獲取資源,如下c為獲取的為原本queue長度

//這裡獲取的c應該是原本的資料,getAndIncrement相當於i++
            c = count.getAndIncrement();
signalNotEmpty方法     
 private void signalNotEmpty() {

        //獲取取出鎖
        final ReentrantLock takeLock = this.takeLock;
     //由於後面需要進行通知操作,所以得先獲取鎖
        takeLock.lock();
        try {
       //通知現在queue裡面有元素了,大家可以來獲取元素了
            notEmpty.signal();
        } finally {
       //解鎖
            takeLock.unlock();
        }
    }

  

  

  

相關文章