Referencia atómica

Tengo algunas preguntas sobre el método AtomicReference.compareAndSet(), según el documento, decía:

Atómicamente establece el valor en el valor actualizado dado si el valor actual == el valor esperado.

Por lo que tengo entendido, el == el operador está comparando la dirección de dos objetos, si es así, ¿cómo funcionará en ejemplos como este?

private AtomicReference<AccessStatistics> stats =
    new AtomicReference<AccessStatistics>(new AccessStatistics(0, 0));
public void incrementPageCount(boolean wasError) {
    AccessStatistics prev, newValue;
    do {
        prev = stats.get();
        int noPages = prev.getNoPages() + 1;
        int noErrors = prev.getNoErrors;
        if (wasError) {
           noErrors++;
        }
        newValue = new AccessStatistics(noPages, noErrors);
    } while (!stats.compareAndSet(prev, newValue));
}

En este fragmento de código, ¿cómo sabe jvm qué campos de AccessStatistics se van a comparar en el compareAndSet()? De hecho, me pregunto cómo funciona toda esta estrategia dado que Java no permite anular == ¿en absoluto? ¡Gracias por cualquier comentario!

preguntado el 27 de julio de 12 a las 17:07

Aquí hay una pregunta muy similar, incluso con el mismo ejemplo: stackoverflow.com/questions/1869959/… -

2 Respuestas

¿Cómo sabe jvm qué campos de AccessStatistics se compararán en compareAndSet()?

no lo hace No está comparando los campos en el objeto. Es solo comparar el referencia del objeto que es lo que dice la documentación. Así es como el AtomicReference trabajos de clase. Como mencionas de la javadocs, usa == y no la equals() método.

Atómicamente establece el valor en el valor actualizado dado si el valor actual == el valor esperado.

Todas las Atomic* Las clases tienen funciones similares. Le permite establecer valores atómicamente mientras se asegura de que otro hilo no sobrescriba su valor. Con compareAndSet(...) debe especificar la referencia del objeto actual para asegurarse de que está actualizando como se esperaba.

En su fragmento de código, está tratando de agregar a un objeto de estadísticas de acceso inmutable. Entonces obtiene el valor actual, lo agrega y luego almacena la nueva estadística en la referencia. Si otro hilo almacenado su estadísticas entre ese tiempo, entonces el compareAndSet devolverá falso y se repite y vuelve a intentarlo. Esto resuelve las condiciones de carrera sin tener que tener un synchronized bloquear.

Respondido 27 Jul 12, 17:07

Gracias Gray, dicho esto, AtomicReference solo se usa para objetos INMUTABLES, esto me aclara mucho las cosas. Asumiría cómo va a funcionar esto si simplemente modificamos algunos campos dentro de prev... Pero en este caso es simplemente Anular el valor de las estadísticas, y eso daría como resultado que el objeto de estadísticas apunte a otro objeto, y == funcionará. - Flecha Cen

@ArrowCen Bueno, no hay nada que requiera inmutabilidad, pero sí, como menciono en mi respuesta, su fragmento de código trata con lo que parece un objeto inmutable. Para tu información: == también funcionará con objetos mutables. - Gris

La JVM no compara los campos en absoluto. Eso sistema económico justo compara si es o no la misma referencia, el mismo puntero en la memoria, o como quieras llamarlo.

Respondido 27 Jul 12, 17:07

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.