Pregunta

El número entero atómica, larga, etc booleano se utilizan para hacer las actualizaciones atómicas a los respectivos tipos ya que puede haber una condición de carrera cuando ejecutamos cualquier manipulación de ellos, por ejemplo ++. Pero ¿cuáles son los diferentes casos con referencias en las que pueda ser tales condiciones de carrera?

Mejores Saludos, Keshav

¿Fue útil?

Solución

referencias AFAIK no están sujetos a condición de carrera debido a que la JVM garantiza que la actualización de referencia es una operación atómica (a diferencia de, por ejemplo, la actualización de un long, donde el inferior y superior 4 bytes se actualizan en dos pasos distintos). El caso sólo es fundamental, como se ha indicado SLaks, es compareAndSet que no es de naturaleza atómica. Que se utilizan muy raramente con referencias nativas, pero es un lenguaje conocido con AtomicReference cuando hay una necesidad de actualizar dos (o más) variables que lógicamente codependiente a la vez. Java concurrencia en la práctica , la sección 15.3.1 publica un ejemplo de esto, el uso de un AtomicReference para actualizar dos variables (almacenado en una clase simple) en una operación atómica.

La razón principal de la existencia de AtomicReference - aparte de la consistencia de las interfaces - es visibilidad y publicación segura . En este sentido, una variable atómica es una "mejor volatile".

Otros consejos

Operaciones como ++ están sujetos a las condiciones de carrera, porque implican múltiples operaciones discretas (fetch, incremento de la tienda).

Configuración de una referencia (a = b) es una sola operación y por lo tanto no está sujeto a condiciones de carrera.

Las operaciones sobre tipos de referencia (a.someMethod()) pueden hacer lo que quieren y pueden o no estar sujetas a condiciones de carrera.

Para que el aprendizaje finalidad i escribió un ConcurrentLinkQueue usando 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;
    }
}
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top