深刻Java集合學習系列:ConcurrentLinkedQueue及其實現原理

http://m.blog.csdn.net/blog/luoyuyou/38039599java


ConcurrentLinkedQueue是一個基於鏈表實現的非阻塞隊列,特色是head和tail是能夠滯後的,甚至tail落到head的後面,準確得說,是當事實的head距離當前head至少兩個link時纔會修改head,這種設計能夠在某些時候提升效率。node

咱們接着來看源碼實現,這裏主要是offer和poll方法:.net

    public boolean offer(E e) {
        checkNotNull(e);
        final Node<E> newNode = new Node<E>(e);

        for (Node<E> t = tail, p = t;;) {
            Node<E> q = p.next;
            if (q == null) {
                // p is last node
                if (p.casNext(null, newNode)) {
                    if (p != t) // hop two nodes at a time
                        casTail(t, newNode);  // Failure is OK.
                    return true;
                }
                // Lost CAS race to another thread; re-read next
            }
            else if (p == q)
                p = (t != (t = tail)) ? t : head;
            else
                // Check for tail updates after two hops.
                p = (p != t && t != (t = tail)) ? t : q;
        }
    }

  • 根據數據構造節點newNode,取得尾節點tail。
  • 接着判斷next,假如不爲空則取它或者取得新的head節點或者新的tail,這裏依據此時是否tail已經滯後head了,以及tail已經被修改。
  • 假如next爲nul,則嘗試CAS添加newNode到當前實際的尾節點p,這裏的CAS操做就是可線性化點。
  • 若是上述成功,則在尾節點距離達到或者超過2個link時更新尾節點。
  • 直接返回true。
poll方法:
    public E poll() {
        restartFromHead:
        for (;;) {
            for (Node<E> h = head, p = h, q;;) {
                E item = p.item;
                if (item != null && p.casItem(item, null)) {
                    if (p != h) // hop two nodes at a time
                        updateHead(h, ((q = p.next) != null) ? q : p);
                    return item;
                }
                else if ((q = p.next) == null) {
                    updateHead(h, p);
                    return null;
                }
                else if (p == q)
                    continue restartFromHead;
                else
                    p = q;
            }
        }
    }
  • 取得頭結點,假如item爲null或者CAS失敗,則須要向後更新p結點,這裏取得新p的方式無非就是沿着next鏈。
  • 當CAS操做成功以後,一樣是距離2個link時更新head結點,而後返回數據。
關於ConcurrentLinkedQueue就是以上這些,整體來講,對於使用者來講,它是個基於鏈表的、不會阻塞的隊列。
相關文章
相關標籤/搜索