讀ConcurrentLinkedQueue


//這是一個無阻塞的隊列沒有加任何鎖全部利用CAS機制實現。效率極高。
//先看構造函數
public ConcurrentLinkedQueue() {
head = tail = new Node<E>(null);
}

public ConcurrentLinkedQueue(Collection<? extends E> c) {
Node<E> h = null, t = null;
for (E e : c) {
//元素不可以爲null
checkNotNull(e);
Node<E> newNode = new Node<E>(e);
//如果頭節點爲空
if (h == null)
h = t = newNode;
else {
//設爲下一個節點
t.lazySetNext(newNode);
t = newNode;
}
}
if (h == null)
h = t = new Node<E>(null);
head = h;
tail = t;
}

//添加元素
public boolean add(E e) {
return offer(e);
}

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;
//當前p是尾節點
if (q == null) {
//利用cas設置值
if (p.casNext(null, newNode)) {
//這意味着一個線程已經設置了tail.next。相當於每兩次更新下tail
if (p != t)
//將newNode設置爲尾節點
casTail(t, newNode); // Failure is OK.
return true;
}
// Lost CAS race to another thread; re-read next
}
//在poll的時候設置了哨兵,正好遇到哨兵了。
else if (p == q)

p = (t != (t = tail)) ? t : head;
else
// Check for tail updates after two hops.
//尋找尾節點。這裏有一個優化假如tail已經被修改直接定位到tail作爲最後一個節點。
p = (p != t && t != (t = tail)) ? t : q;
}
}


//獲取並移除一個節點
public E poll() {
restartFromHead:
for (;;) {
for (Node<E> h = head, p = h, q;;) {
E item = p.item;
//如果item有值並且將item設置爲null成功
if (item != null && p.casItem(item, null)) {
//這和offer思路一樣
if (p != h)
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;
}
}
}

//只獲取但是不移除
public E peek() {
restartFromHead:
for (;;) {
for (Node<E> h = head, p = h, q;;) {
E item = p.item;
if (item != null || (q = p.next) == null) {
//設置p爲頭結點,也就是過濾p前面的空節點。
updateHead(h, p);
return item;
}
else if (p == q)
continue restartFromHead;
else
p = q;
}
}
}

//判斷隊列是否爲空
public boolean isEmpty() {
return first() == null;
}

//找到第一個不爲null的節點。並且設置爲頭節點。
Node<E> first() {
restartFromHead:
for (;;) {
for (Node<E> h = head, p = h, q;;) {
boolean hasItem = (p.item != null);
if (hasItem || (q = p.next) == null) {
updateHead(h, p);
return hasItem ? p : null;
}
else if (p == q)
continue restartFromHead;
else
p = q;
}
}
}

//獲取元素個數
public int size() {
int count = 0;
for (Node<E> p = first(); p != null; p = succ(p))
if (p.item != null)
// Collection.size() spec says to max out
if (++count == Integer.MAX_VALUE)
break;
return count;
}


final Node<E> succ(Node<E> p) {
Node<E> next = p.next;
return (p == next) ? head : next;
}

//包含某個元素和size的實現差不多
public boolean contains(Object o) {
if (o == null) return false;
for (Node<E> p = first(); p != null; p = succ(p)) {
E item = p.item;
if (item != null && o.equals(item))
return true;
}
return false;
}

//移除一個元素
public boolean remove(Object o) {
if (o == null) return false;
Node<E> pred = null;
for (Node<E> p = first(); p != null; p = succ(p)) {
E item = p.item;
if (item != null &&
o.equals(item) &&
p.casItem(item, null)) {
Node<E> next = succ(p);
if (pred != null && next != null)
pred.casNext(p, next);
return true;
}
pred = p;
}
return false;
}

//新增全部
public boolean addAll(Collection<? extends E> c) {
if (c == this)
throw new IllegalArgumentException();

// Copy c into a private chain of Nodes
//將c變爲鏈表結構
Node<E> beginningOfTheEnd = null, last = null;
for (E e : c) {
checkNotNull(e);
Node<E> newNode = new Node<E>(e);
if (beginningOfTheEnd == null)
beginningOfTheEnd = last = newNode;
else {
last.lazySetNext(newNode);
last = newNode;
}
}
if (beginningOfTheEnd == null)
return false;

// Atomically append the chain at the tail of this collection
for (Node<E> t = tail, p = t;;) {
Node<E> q = p.next;
//如果當前p正好是隊尾
if (q == null) {
// p is last node
//CAS設置值
if (p.casNext(null, beginningOfTheEnd)) {
//可能隊尾已經被其他線程設置過了
if (!casTail(t, last)) {
//再次嘗試
t = tail;
if (last.next == null)
casTail(t, last);
}
return true;
}

}
else if (p == q)

p = (t != (t = tail)) ? t : head;
else

p = (p != t && t != (t = tail)) ? t : q;
}
}

public Object[] toArray() {

ArrayList<E> al = new ArrayList<E>();
for (Node<E> p = first(); p != null; p = succ(p)) {
E item = p.item;
if (item != null)
al.add(item);
}
return al.toArray();
}

//這個實現和其他集合的實現不太一樣。我個人覺得是因爲計算size有開銷。所以這樣寫提升效率。
public <T> T[] toArray(T[] a) {

int k = 0;
Node<E> p;
for (p = first(); p != null && k < a.length; p = succ(p)) {
E item = p.item;
if (item != null)
a[k++] = (T)item;
}
//如果a的length>隊列的length
if (p == null) {
if (k < a.length)
a[k] = null;
return a;
}

//如果a的length<隊列的length
ArrayList<E> al = new ArrayList<E>();
for (Node<E> q = first(); q != null; q = succ(q)) {
E item = q.item;
if (item != null)
al.add(item);
}
return al.toArray(a);
}

//迭代器
private class Itr implements Iterator<E> {

private Node<E> nextNode;

private E nextItem;

private Node<E> lastRet;

Itr() {
advance();
}


private E advance() {
lastRet = nextNode;
E x = nextItem;

Node<E> pred, p;
if (nextNode == null) {
p = first();
pred = null;
} else {
pred = nextNode;
p = succ(nextNode);
}

for (;;) {
if (p == null) {
nextNode = null;
nextItem = null;
return x;
}
E item = p.item;
if (item != null) {
nextNode = p;
nextItem = item;
return x;
} else {
// skip over nulls
Node<E> next = succ(p);
if (pred != null && next != null)
pred.casNext(p, next);
p = next;
}
}
}

public boolean hasNext() {
return nextNode != null;
}

public E next() {
if (nextNode == null) throw new NoSuchElementException();
return advance();
}

public void remove() {
Node<E> l = lastRet;
if (l == null) throw new IllegalStateException();

l.item = null;
lastRet = null;
}
}
發佈了149 篇原創文章 · 獲贊 1 · 訪問量 1萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章