Pregunta

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

Establece atómicamente el valor al valor actualizado dado si el valor actual == el valor esperado.

Hasta donde 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 deben compararse 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!

¿Fue útil?

Solución

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

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

Establece atómicamente el valor al valor actualizado dado si el valor actual == el valor esperado.

Toda la Atomic* Las clases tienen funciones similares.Le permite establecer valores de forma atómica 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á intentando agregarlo 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 es estadísticas entre ese tiempo, entonces el compareAndSet devolverá falso y se repetirá y lo intentará de nuevo.Esto resuelve las condiciones de carrera sin tener que tener un synchronized bloquear.

Otros consejos

La JVM no compara los campos en absoluto.Él justo compara si es o no la misma referencia, el mismo puntero en la memoria o como quieras llamarlo.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top