2010-05-28 44 views
6

he utilizado AtomicLong muchas veces, pero nunca he tenido que utilizar AtomicReferenceCuándo usar AtomicReference (Java)? ¿Es realmente necesario?

Parece que AtomicReference hace bien (he copiado el código de otra cuestión stackoverflow ):

public synchronized boolean compareAndSet(List<Object> oldValue, List<Object> newValue) { 
    if (this.someList == oldValue) { 
     // someList could be changed by another thread after that compare, 
     // and before this set 
     this.someList = newValue; 
     return true; 
    } 
    return false; 
} 

O

public synchronized boolean compareAndSet(List<Object> oldValue, List<Object> newValue) { 
    if (this.someList == oldValue || this.someList.equals(oldValue)) { 
     // someList could be changed by another thread after that compare, 
     // and before this set 
     this.someList = newValue; 
     return true; 
    } 
    return false; 
} 

Supongamos que this.someList se marca como volátil.

No estoy seguro de cuál es realmente porque el javadoc y el código para esa clase no son claros si se usa .equals.

Viendo cómo los métodos anteriores no son tan difíciles de escribir ¿Alguien alguna vez ha usado AtomicReference?

+6

[Ellos] (http://www.google.com/search?q=%22import+java.util.concurrent.atomic.atomicreference%22&) alguna vez lo han usado. – BalusC

Respuesta

11

Es una referencia , así que eso es lo que se compara. La documentación deja en claro que es una comparación de identidad, incluso usando la operación == en its description.

Uso AtomicReference y otras clases atómicas con mucha frecuencia. La creación de perfiles muestra que funcionan mejor que los métodos equivalentes mediante la sincronización. Por ejemplo, una operación get() en un AtomicReference requiere solo una recuperación desde la memoria principal, mientras que una operación similar usando synchronized primero debe enjuagar cualquier valor almacenado en caché por hilos en la memoria principal y luego realizar su recuperación.

Las clases AtomicXXX proporcionan acceso a la compatibilidad nativa para operaciones de comparación y canje (CAS). Si el sistema subyacente lo admite, CAS será más rápido que cualquier esquema preparado con bloques synchronized en Java puro.

+1

Por supuesto que soy un idiota. Es java.lang.ref Estaba pensando que era algo así como AtomicObject si hubiera uno. –

+0

¿Cómo comentaría este punto de referencia: https://edgblog.wordpress.com/2013/10/01/synchronization-vs-atomicreference-test/? –

+0

@ WaldemarWosiński Usar un 'AtomicLong' para mantener el valor será más rápido que un' largo' en un bloque 'sincronizado', que sería una comparación directa de manzanas a manzanas. La asignación de objetos representa parte de la diferencia, pero esto se ve agravado por los reintentos debido a las comparaciones fallidas en CAS. Si le importa la velocidad en las aplicaciones concurrentes, adhiérase a las operaciones que están libres de efectos secundarios (como las implementaciones 'long' o' AtomicLong'). – erickson

Cuestiones relacionadas