Вопрос

Атомное целое число, длительное, логическое и т. Д. Используется для выполнения любых атомных обновлений к соответствующим типам, поскольку может быть состояние гонки, когда мы выполняем любые манипулирования на них, например, ++. Но каковы разные случаи со ссылками, где могут быть такие условия расы?

С уважением,
Кешав

Это было полезно?

Решение

Ссылки AFAIK не подвержены состоянии гонки, потому что JVM гарантирует, что эталонное обновление является атомной операцией (в отличие от, например, обновление long, где нижние и верхние 4 байта обновляются в двух разных шагах). Единственный критический случай, как отметил Слакс, compareAndSet который не атомной природой. Это очень редко используется с родными ссылками, но это известная идиома с AtomicReference Когда необходимо обновить два (или более) логически кодовых переменных одновременно. Java параллелизм на практике, раздел 15.3.1 публикует пример для этого, используя AtomicReference Чтобы обновить две переменные (хранится в простом классе) в одной атомной работе.

Основная причина существования AtomicReference - Помимо консистенции интерфейсов - это видимость а также Безопасная публикация. Отказ В этом смысле атомная переменная является «лучше volatile".

Другие советы

Операции типа ++ подлежат гоночным условиям, потому что они включают в себя несколько незаметных операций (приема, приращение, магазин).

Установка ссылки (a = b) - это единственная операция и, таким образом, не подвержена гоночным условиям.

Операции по ссылочным типам (a.someMethod()) может сделать все, что они хотят и могут или не могут подвергаться воздействию расходов.

Для изучения цели я написал ConculrentLinkQueue, используя AtomicReference.

      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;
    }
}
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top