我正在尝试使用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