Frage

Die Atom integer, long, boolean usw. werden verwendet, um all Atom-Updates für die jeweiligen Typen zu tun, da es eine Race-Bedingung sein kann, wenn wir ihnen eine Manipulation ausführen, z ++. Aber was die verschiedenen Fälle mit Hinweisen, wo es kann eine solche Rennbedingungen sein?

Die besten Grüße, Keshav

War es hilfreich?

Lösung

AFAIK Referenzen unterliegen nicht die Race-Bedingung, da die JVM gewährleistet, dass die Referenz Update ist eine atomare Operation (im Gegensatz zu beispielsweise einem long aktualisieren, wo die unteren und oberen 4 Byte in zwei getrennten Schritten aktualisiert werden). Der einzige kritische Fall, wie SLaks erwähnt, ist compareAndSet, die von Natur aus nicht atomar ist. Dass sehr selten mit einheimischen Referenzen verwendet, aber es ist eine bekannte Redewendung mit AtomicReference, wenn es eine Notwendigkeit, zwei zu aktualisieren ist (oder mehr) logisch codependent Variablen auf einmal. Java Concurrency in Practice , Abschnitt 15.3.1 veröffentlicht ein Beispiel dafür, eine AtomicReference mit zwei Variablen zu aktualisieren (in einer einfachen Klasse gespeichert) in einer atomaren Operation.

Der Hauptgrund für die Existenz von AtomicReference - abgesehen von Konsistenz von Schnittstellen - ist Sichtbarkeit und sichere Veröffentlichung . In diesem Sinne ist eine atomare Variable ist ein „besserer volatile“.

Andere Tipps

Operationen wie ++ unterliegen Rennbedingungen, weil sie mehr diskreten Operationen (holen, erhöht, zu speichern) einzubeziehen.

Einstellen einer Referenz (a = b) ist ein Einzelbetrieb und ist somit nicht unter Rennbedingungen.

Operationen auf Referenztypen (a.someMethod()) können tun, was sie wollen und können oder nicht unter Rennbedingungen sein.

Für Zweck Lernen habe ich ein ConcurrentLinkQueue AtomicReference verwenden.

      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;
    }
}
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top