1. 程式人生 > >LinkedBlockingQueue中put源碼分析

LinkedBlockingQueue中put源碼分析

資源 線程 ID 數量 integer cond 滿了 incr IT

查看源碼得知:

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(); } }

  

  

LinkedBlockingQueue中put源碼分析