java - 正确使用 AtomicReference.compareAndSet 实现堆栈

标签 java concurrency atomic

我正在试验 java.util.concurrent 并试图找出如何正确使用 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;
    }
  } 
  ...................
}

最佳答案

是的,这正是它应该如何使用。

也许下面的语法会更优雅:

Node<T> oldTop = null;
Node<T> newTop = null;
do {
    oldTop=topOfStack.get();
    newTop=new Node<T>(e,oldTop);
} while (!topOfStack.compareAndSet(oldTop, newTop));

关于java - 正确使用 AtomicReference.compareAndSet 实现堆栈,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5553398/

相关文章:

java - C++ 中 java.util.ResourceBundle 的等效性

java - Windows 上的路径分隔符不明确 - 如何处理?

java - Servlet 中的线程和并发

java - 我在哪里可以找到 Java 库中 `native` 方法的源代码?

java - 捕获 ANTLR 中的错​​误并查找父级

java - 将方法声明为 `return this` 有什么好方法吗?

javafx - 为什么 ExecutorService 不返回我的任务结果?

java - 通过不同线程同时读取和更改变量

java - 原子变量是否保证内存可见性?

MySQL/JDBC : How to "atomically" remove rows and then add one new row