在前面的篇章中,我們詳細分析了AQS,並提到了裡面一個關鍵資料結構:所有阻塞線程組成的一個等待隊列,這個隊列是用單向無鎖鏈表實現的。
今天所講的ConcurrentLinkedQueue,其實現和AQS中的無鎖隊列基本一樣。所以,如果你深刻理解了AQS,ConcurrentLinkedQueue也就知道了。出於內容的完整性,在此還是列一下其源碼:
public class ConcurrentLinkedQueue<E> extends AbstractQueue<E> implements Queue<E>, java.io.Serializable { //單向鏈表的Node private static class Node<E> { private volatile E item; private volatile Node<E> next;``` 。。。 } //整個隊列記錄1頭1尾2個結點 private transient volatile Node<E> head = new Node<E>(null); private transient volatile Node<E> tail = head; //入隊,也即cas tail (樂觀鎖) public boolean offer(E e) { if (e == null) throw new NullPointerException(); Node<E> n = new Node<E>(e); retry: for (;;) { Node<E> t = tail; Node<E> p = t; for (int hops = 0; ; hops++) { Node<E> next = succ(p); if (next != null) { if (hops > HOPS && t != tail) continue retry; p = next; } else if (p.casNext(null, n)) { if (hops >= HOPS) casTail(t, n); // Failure is OK. return true; } else { p = succ(p); } } } } //出隊,cas head,樂觀鎖 public E poll() { Node<E> h = head; Node<E> p = h; for (int hops = 0; ; hops++) { E item = p.getItem(); if (item != null && p.casItem(item, null)) { if (hops >= HOPS) { Node<E> q = p.getNext(); updateHead(h, (q != null) ? q : p); } return item; } Node<E> next = succ(p); if (next == null) { updateHead(h, p); break; } p = next; } return null; } 。。。}