看JDK源碼FutureTask的時候看到裏面有描述用到Triber stack,想到不知道這是什麼數據結構,於是來學習一下。
代碼如下:
public class FutureTask<V> implements RunnableFuture<V> {
/** Treiber stack of waiting threads */
private volatile WaitNode waiters;
}
等待節點用的是一個Treiber stack,而WaitNode的結構如下:
/**
* Simple linked list nodes to record waiting threads in a Treiber
* stack. See other classes such as Phaser and SynchronousQueue
* for more detailed explanation.
*/
static final class WaitNode {
volatile Thread thread;
volatile WaitNode next;
WaitNode() { thread = Thread.currentThread(); }
}
看不出來有什麼端倪,又google一番,參考wikipedia
The Treiber stack algorithm is a scalable lock-free stack utilizing the fine-grained concurrency primitive compare-and-swap.[1] It is believed that R. Kent Treiber was the first to publish it in his 1986 article "Systems Programming: Coping with Parallelism".[2]
即Treiber stack是一個使用細粒度的併發原語compare-and-swap(CAS)的可擴展的無鎖棧。R. Kent Treiber在他的文章Systems Programming: Coping with Parallelism
中首次提出。
即通過CAS來保證入棧和出棧的線程安全,相對來說實現起來比較簡單。
如下所示:
public class TreiberStack<E> {
AtomicReference<Node<E>> top = new AtomicReference<>();
public void push(E element) {
Node<E> newHead = new Node<>(element);
Node<E> oldHead;
do {
oldHead = top.get();
newHead.next = oldHead;
} while (!top.compareAndSet(oldHead, newHead));
}
public E pop() {
Node<E> newHead;
Node<E> oldHead;
do {
oldHead = top.get();
if (null == oldHead) {
return null;
}
newHead = oldHead.next;
} while (!top.compareAndSet(oldHead, newHead));
return oldHead.emement;
}
final class Node<E> {
private final E emement;
private Node next;
public Node(E element) {
this.emement = element;
}
}
}