2012-03-21 23 views
5

¿Es esta clase segura para subprocesos?AtomicInteger vs getters/setters sincronizados

¿Es posible ver valores inconsistentes? Digamos que inicialmente el valor de a es 80. El hilo 1 llama al setA(100) y entra en la función pero todavía no llamó a a.set(100) y el hilo 2 al mismo tiempo llama al getA(). ¿Es posible que el Tema 2 vea 80?

public class A { 
    private AtomicInteger a; 

    public int getA() { 
     return a.get() 
    } 

    public void setA(int newVal){ 
     a.set(newVal); 
    } 
} 

Sé que sincronizarlo garantizará que el hilo 2 vea 100, pero no está seguro con AtomicInteger.

Respuesta

9

¿Esta clase es segura para subprocesos?

Sí, lo es.

El hilo 1 llama a setA (100) e ingresa a la función pero aún no llamó a .set (100) y al hilo 2 llamadas concurrentemente getA(). ¿Es posible que el Tema 2 vea 80?

Sí. Hasta que el código de barrera de memoria que sincroniza el campo volátil dentro de AtomicInteger completa, la condición de carrera puede mostrar 80 o 100.

Thread 1 podría incluso entrar en el método AtomicInteger.set y ser antes de la asignación del campo interior y siendo el 80 pueden ser devueltos por el método get AtomicInteger.get.

No existen garantías sobre cuando los valores se actualizarán en otros temas. Lo que está garantizado es que cuando se complete el get(), obtendrá el valor sincronizado más reciente y cuando el set() finalice, todos los demás hilos verán las actualizaciones.

No hay garantía en cuanto a la temporización de las llamadas getter y setter en diferentes subprocesos.

1

Como observó @Gray, existe la posibilidad de una condición de carrera aquí.

Llamar a get y luego set no es una operación atómica. The Atomic* classes ofrecen una operación de actualización condicional atómica sin bloqueo, compareAndSet - debe usarla para la seguridad del hilo.

Cuestiones relacionadas