簡介
Treiber Stack在 R. Kent Treiber在1986年的論文Systems Programming: Coping with Parallelism中首次出現。它是一種無鎖並發棧,其無鎖的特性是基於CAS原子操作實現的。
實現
下面給出的Java語言實現為《Java並發編程實戰》一書的15.4.1小結中的實現。Treiber Stack的實現套路很簡單,就是CAS+重試,不需要任何注釋就能輕松的看懂代碼。
@ThreadSafe
public class ConcurrentStack <E> {
AtomicReference<Node<E>> top = new AtomicReference<Node<E>>();
public void push(E item) {
Node<E> newHead = new Node<E>(item);
Node<E> oldHead;
do {
oldHead = top.get();
newHead.next = oldHead;
} while (!top.compareAndSet(oldHead, newHead));
}
public E pop() {
Node<E> oldHead;
Node<E> newHead;
do {
oldHead = top.get();
if (oldHead == null)
return null;
newHead = oldHead.next;
} while (!top.compareAndSet(oldHead, newHead));
return oldHead.item;
}
private static class Node <E> {
public final E item;
public Node<E> next;
public Node(E item) {
this.item = item;
}
}
}
JDK中的使用
JDK中的FutureTask使用了Treiber Stack。關於FutureTask的源碼解讀,可以參考我的博文FutureTask源碼解讀。FutureTask用了Treiber Stack來維護等待任務完成的線程,在FutureTask的任務完成/取消/異常后在finishCompletion鈎子方法中會喚醒棧中等待的線程。
參考
《Java並發編程實戰》
Treiber Stack