2010-09-19 71 views
1

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

最好的问候,
凯沙夫因为它们涉及

回答

2

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

的主要原因为AtomicReference存在 - 除了接口的一致性 - 是知名度安全出版物。在这个意义上,原子变量是“更好的volatile”。

2

操作,如++受到竞争条件多谨慎操作(读取,增量,商店)。

设置参考(a = b)是一项单一操作,因此不会受到竞争条件的限制。

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

+0

那么为什么我们有一个类的AtomicReference – keshav84 2010-09-19 12:56:24

+1

@keshu:'compareAndSet'是受竞争情况,因为它涉及到两个操作。 – SLaks 2010-09-19 12:57:32

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; 
    } 
}