1

原子整数、长整数、布尔值等用于对各自类型进行任何原子更新,因为当我们对它们执行任何操作时可能存在竞争条件,例如 ++。但是,在可能存在这种竞争条件的情况下,引用的不同情况是什么?

最好的问候,
凯沙夫

4

3 回答 3

2

AFAIK 引用不受竞争条件的影响,因为 JVM 保证引用更新是原子操作(与更新 a 不同long,其中低 4 字节和高 4 字节在两个不同的步骤中更新)。正如 SLaks 所指出的,唯一的关键情况是compareAndSet本质上不是原子的。这很少与本地引用一起使用,但它是一个已知的习惯用法,AtomicReference当需要一次更新两个(或更多)逻辑上相互依赖的变量时。Java 并发实践,第 15.3.1 节为此发布了一个示例,使用AtomicReference一个原子操作更新两个变量(存储在一个简单的类中)。

存在的主要原因AtomicReference——除了接口的一致性——是可见性安全发布。从这个意义上说,原子变量是“更好的volatile”。

于 2010-09-19T13:17:12.520 回答
2

像这样的操作++会受到竞争条件的影响,因为它们涉及多个谨慎的操作(获取、增量、存储)。

设置引用 ( a = b) 是一个单独的操作,因此不受竞争条件的影响。

对引用类型 ( a.someMethod()) 的操作可以做任何他们想做的事情,并且可能会或可能不会受到竞争条件的影响。

于 2010-09-19T12:55:30.050 回答
0

出于学习目的,我使用 AtomicReference 编写了一个 ConcurrentLinkQueue。

      package concurrent.AtomicE;

      import java.util.concurrent.atomic.AtomicReference;

     public class ConcurrentLinkQueue<V> {
       private final AtomicReference<Node> firstNodePointer = new AtomicReference<Node>();

   public void fastOffer(final V data){
    final Node<V> newNode = new Node<V>(data,Thread.currentThread().getName());
    System.out.println(newNode);
    AtomicReference<Node> pointer = firstNodePointer;
    for(;;){
        if(pointer.get() == null){
            if(pointer.compareAndSet(null,newNode)){
                return;
            }
        }
        pointer = pointer.get().getNext();
    }
}

private static class Node<V>{
    private AtomicReference<Node> next = new AtomicReference<Node>();
    private volatile V data = null;
    private String threadName = "";

    Node(V data1,String threadName){
        this.data = data1;
        this.threadName = threadName;
    }

    @Override
    public String toString() {
        return  "threadName=" + threadName +
                ", data=" + data;
    }

    private AtomicReference<Node> getNext() {
        return next;
    }

    private void setNext(AtomicReference<Node> next) {
        this.next = next;
    }

    private V getData() {
        return data;
    }

    private void setData(V data) {
        this.data = data;
    }
}
于 2013-08-05T17:59:21.383 回答