我正在嘗試使用java.util.concurrent並試圖解決如何正確使用AtomicReference.compareAndSet來管理對單個共享狀態的併發訪問。正確使用AtomicReference.compareAndSet進行堆棧實現
特別是:compareAndSet的正確性和安全性如下:任何陷阱?
我的測試類是一個基於節點鏈表的簡單堆棧。
public class LinkedStack<T> {
AtomicReference<Node<T>> topOfStack=new AtomicReference<Node<T>>();
public T push(T e) {
while(true) {
Node<T> oldTop=topOfStack.get();
Node<T> newTop=new Node<T>(e,oldTop);
if (topOfStack.compareAndSet(oldTop, newTop)) break;
}
return e;
}
public T pop() {
while(true) {
Node<T> oldTop=topOfStack.get();
if (oldTop==null) throw new EmptyStackException();
Node<T> newTop=oldTop.next;
if (topOfStack.compareAndSet(oldTop, newTop)) return oldTop.object;
}
}
private static final class Node<T> {
final T object;
final Node<T> next;
private Node (T object, Node<T> next) {
this.object=object;
this.next=next;
}
}
...................
}
唯一讓我暫停的不是你如何使用'AtomicReference',而是你從'push'返回的東西。我很快就會期望'push'不會返回任何東西或者被埋沒的價值,而不是你自己推動的價值。 – 2011-04-05 14:43:18
@Mark,是的,這讓我停下了,但我只是想與Java的標準堆棧保持一致 - http://download.oracle.com/javase/1.5.0/docs/api/java/util/Stack .html#push(E) - 承認這是一個稍微奇怪的返回定義 – mikera 2011-04-05 14:45:39
可能最好假裝該類不存在的原因很多(它不是一個接口,當它應該是,它使用從Vector的繼承而不是組成等等)。我會從[Deque](http://download.oracle.com/javase/6/docs/api/java/util/Deque.html#push(E))接口中獲取提示,而不是其實現優於' Stack'。它是在Java 6中引入的,'Stack'的Javadoc被改爲建議在'Stack'上使用'Deque'。 – 2011-04-05 14:47:47