AtomicInteger lazySet vs set


¿Cuál es la diferencia entre los métodos lazySet y set de AtomicInteger? La documentación de no tiene mucho que decir sobre lazySet:

Eventualmente establece el valor dado.

Parece que el valor almacenado no será de inmediato en el valor deseado sino que se va a establecer algún momento en el futuro. Pero, ¿cuál es el uso práctico de este método? ¿Algún ejemplo?

Author: David Harkness, 2009-09-23

6 answers

Citado directamente de "JDK-6275329: Agregar métodos lazySet a clases atómicas":

Como probablemente el último pequeño seguimiento de JSR166 para Mustang, hemos añadido un método "lazySet" a las clases atómicas (AtomicInteger, AtomicReference, etc.). Este es un nicho método que a veces es útil cuando se afina el código usando estructuras de datos sin bloqueo. La semántica es que la escritura está garantizada para no ser reordenado con cualquier anterior escribir, pero puede ser reordenado con operaciones posteriores (o de manera equivalente, podría no ser visible para otros hilos) hasta alguna otra escritura volátil o acción de sincronización ocurre).

El caso de uso principal es para anular campos de nodos en estructuras de datos sin bloqueo únicamente para evitar retención de basura a largo plazo; se aplica cuando es inofensivo si otros hilos ven valores no nulos por un tiempo, pero como para asegurarse de que las estructuras son finalmente GCable. En tal casos, usted puede conseguir mejor rendimiento, evitando los costos de la escritura volátil nula. Hay algunos otros casos de uso a lo largo de estas líneas para no basado en referencias atomics también, por lo que el método es compatible con todos los Clases AtomicX.

Para las personas que les gusta pensar en estas operaciones en términos de barreras a nivel de máquina en multiprocesadores comunes, lazySet proporciona una barrera tienda-tienda que precede (que es un no-op o muy barato en las plataformas actuales), pero no barrera de almacenamiento (que suele ser la parte cara de una escritura volátil).

 100
Author: yawn,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-09-25 18:50:58

LazySet se puede utilizar para la comunicación entre hilos rmw, porque xchg es atómica, en cuanto a la visibilidad, cuando el proceso de subproceso de escritor modifica una ubicación de línea de caché, el procesador del hilo de lector lo verá en la siguiente lectura, porque el protocolo de coherencia de caché de la cpu intel garantizará que lazySet funcione, pero la línea de caché se actualizará en la siguiente lectura, de nuevo, la CPU tiene que ser lo suficientemente moderna.

Http://sc.tamu.edu/systems/eos/nehalem.pdf Para Nehalem, que es un multiprocesador plataforma, los procesadores tienen la capacidad de "espiar" (espiar) el bus de direcciones para los accesos de otros procesadores a la memoria del sistema y a sus cachés internos. Utilizan esta capacidad de espionaje para mantener sus cachés internos consistentes tanto con la memoria del sistema como con los cachés de otros procesadores interconectados. Si a través de snooping un procesador detecta que otro procesador tiene la intención de escribir en una ubicación de memoria que actualmente tiene en caché en estado compartido, el procesador de snooping invalidará su bloque de caché lo obliga a realizar un relleno de línea de caché la próxima vez que acceda a la misma ubicación de memoria.

Oracle hotspot jdk para arquitectura de cpu x86- >

LazySet == inseguro.putOrderedLong = = xchg rw( asm instruction that serve as a soft barrier costing 20 cycles on nehelem intel cpu)

En x86 (x86_64) tal barrera es mucho más barata en cuanto a rendimiento que volátil o AtomicLong getAndAdd,

En un escenario de cola de un productor, un consumidor, xchg soft barrier puede forzar la línea de códigos antes del lazySet (secuencia + 1) para que el hilo productor suceda ANTES de cualquier código de hilo consumidor que consuma (trabaje en) los nuevos datos, por supuesto, el hilo consumidor necesitará verificar atómicamente que la secuencia del productor se incrementó exactamente uno usando un compareAndSet (secuencia, secuencia + 1).

Rastreé después del código fuente de Hotspot para encontrar la asignación exacta de lazySet a cpp codificar: http://hg.openjdk.java.net/jdk7/jdk7/hotspot/file/9b0ca45cd756/src/share/vm/prims/unsafe.cpp Unsafe_setOrderedLong - > SET_FIELD_VOLATILE definition - > OrderAccess: release_store_fence. Para x86_64, OrderAccess: release_store_fence se define como el uso de la instrucción xchg.

Puedes ver cómo se define exactamente en jdk7 (doug lea está trabajando en algunas cosas nuevas para JDK 8): http://hg.openjdk.java.net/jdk7/jdk7/hotspot/file/4fc084dac61e/src/os_cpu/linux_x86/vm/orderAccess_linux_x86.inline.hpp

También puede usar los hdis para desensamblar el ensamblado del código lazySet en acción.

Hay otra pregunta relacionada: ¿Necesitamos mfence cuando usamos xchg

 13
Author: porkchop,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 12:10:33

Una discusión más amplia de los orígenes y la utilidad de lazySet y el supuesto subyacente se puede encontrar aquí: http://psy-lob-saw.blogspot.co.uk/2012/12/atomiclazyset-is-performance-win-for.html

Para resumir: lazySet es una escritura volátil débil en el sentido de que actúa como una tienda-tienda y no como una valla de carga de tienda. Esto se reduce a que lazySet se compila JIT a una instrucción MOV que no puede ser reordenada por el compilador en lugar de la significativamente más costosa instrucción utilizada para un conjunto volátil.

Al leer el valor siempre terminas haciendo una lectura volátil(con un Átomo*.get() en cualquier caso).

LazySet ofrece a un solo escritor un mecanismo de escritura volátil consistente, es decir, es perfectamente legítimo que un solo escritor use lazySet para incrementar un contador, múltiples hilos incrementando el mismo contador tendrán que resolver las escrituras competidoras usando CAS, que es exactamente lo que sucede bajo las cubiertas de Atomic* para incAndGet.

 9
Author: Nitsan Wakart,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-12-24 11:42:44

Del resumen del paquete atómico concurrente

LazySet tiene los efectos de memoria de escribir (asignar) una variable volátil, excepto que permite reordenamientos con acciones de memoria posteriores (pero no anteriores) que no imponen restricciones de reordenamiento con escrituras ordinarias no volátiles. Entre otros contextos de uso, lazySet puede aplicarse cuando se anula, por el bien de la recolección de basura, una referencia a la que nunca se accede de nuevo.

Si usted es curioso acerca de lazySet entonces te debes otras explicaciones también

Los efectos de memoria para accesos y actualizaciones de atomics en general siga las reglas para volátiles, como se indica en la sección 17.4 de Java™ Especificación del Idioma.

Get tiene los efectos de memoria de leer una variable volátil.

Set tiene los efectos de memoria de escribir (asignar) una variable volátil.

LazySet tiene los efectos de memoria de la escritura (asignando) una variable volátil excepto que permite reordenamientos con acciones de memoria posteriores (pero no anteriores) que no imponen reordenamiento restricciones con escrituras ordinarias no volátiles. Entre otros usos contextos, lazySet puede aplicarse cuando se anula, por el bien de la basura colección, una referencia a la que nunca se vuelve a acceder.

WeakCompareAndSet atómicamente lee y escribe condicionalmente una variable, pero no crea ninguna sucede-antes de los pedidos, así proporciona no hay garantías con respecto a lecturas y escrituras anteriores o posteriores de cualquier variable que no sea el objetivo del weakCompareAndSet. compareAndSet y todas las demás operaciones de lectura y actualización, como getAndIncrement, tienen los efectos de memoria tanto de lectura como de escritura variables volátiles.

 6
Author: Ajeet Ganga,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-11-08 10:31:58

Aquí está mi entendimiento, corrígeme si estoy equivocado: Puedes pensar en lazySet() como "semi" volátil: es básicamente una variable no volátil en términos de lectura por otros hilos, es decir, el valor establecido por lazySet puede no ser visible para otros hilos. Pero se vuelve volátil cuando ocurre otra operación de escritura (puede ser de otros hilos). El único impacto de lazySet que puedo imaginar es compareAndSet. Así que si utilizas lazySet(), get() de otros hilos todavía puede obtener el valor antiguo, pero compareAndSet() siempre tendrá el nuevo valor ya que es una operación de escritura.

 3
Author: jyluo,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-08-21 10:51:55

Re: intento de silenciarlo -

Puede pensar en esto como una forma de tratar un campo volátil como si no fuera volátil para una operación de almacén en particular (por ejemplo: ref = null;).

Eso no es perfectamente exacto, pero debería ser suficiente para que puedas tomar una decisión entre "OK, realmente no me importa" y "Hmm, déjame pensar en eso un poco".

 2
Author: Paul Mclachlan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-04-23 21:20:59