Mientras intentaba entender cómo SubmissionPublisher
( código fuente en Java SE 10, OpenJDK | docs ), una nueva clase agregada a Java SE en la versión 9, se implementó, me topé con algunas llamadas a la API VarHandle
que no conocía anteriormente:
fullFence
` acquireFence
` releaseFence
, loadLoadFence
y storeStoreFence
.
Después de investigar un poco, especialmente con respecto al concepto de barreras / vallas de memoria (he oído hablar de ellos anteriormente, sí; pero nunca los usé, por lo que no estaba muy familiarizado con su semántica), creo que tengo una comprensión básica de lo que son . No obstante, dado que mis preguntas pueden surgir de una idea errónea, quiero asegurarme de haber acertado en primer lugar:
Las barreras de memoria son restricciones de reordenamiento con respecto a las operaciones de lectura y escritura.
Las barreras de memoria se pueden clasificar en dos categorías principales: barreras de memoria unidireccionales y bidireccionales, dependiendo de si establecen restricciones en lecturas o escrituras o en ambas.
C ++ admite una variedad de barreras de memoria , sin embargo, estas no coinciden con las proporcionadas por
VarHandle
. Sin embargo, algunas de las barreras de memoria disponiblesVarHandle
proporcionan efectos de ordenamiento que son compatibles con sus correspondientes barreras de memoria C ++.#fullFence
es compatible conatomic_thread_fence(memory_order_seq_cst)
#acquireFence
es compatible conatomic_thread_fence(memory_order_acquire)
#releaseFence
es compatible conatomic_thread_fence(memory_order_release)
#loadLoadFence
y#storeStoreFence
no tiene contraparte compatible con C ++
La palabra compatible parece ser realmente importante aquí, ya que la semántica difiere claramente en lo que respecta a los detalles. Por ejemplo, todas las barreras de C ++ son bidireccionales, mientras que las barreras de Java no lo son (necesariamente).
- La mayoría de las barreras de memoria también tienen efectos de sincronización. Esos dependen especialmente del tipo de barrera utilizada y las instrucciones de barrera ejecutadas previamente en otros hilos. Como todas las implicaciones que tiene una instrucción de barrera son específicas del hardware, me quedaré con las barreras de nivel superior (C ++). En C ++, por ejemplo, los cambios realizados antes de una instrucción de barrera de liberación son visibles para un subproceso que ejecuta una instrucción de barrera de adquisición .
¿Son correctas mis suposiciones? Si es así, mis preguntas resultantes son:
¿Las barreras de memoria disponibles
VarHandle
causan algún tipo de sincronización de memoria?Independientemente de si causan sincronización de memoria o no, ¿para qué pueden ser útiles las restricciones de reordenamiento en Java? El modelo de memoria de Java ya ofrece algunas garantías muy sólidas con respecto a los pedidos cuando intervienen campos volátiles, bloqueos u
VarHandle
operaciones similares#compareAndSet
.
En caso de que esté buscando un ejemplo: lo mencionado anteriormente BufferedSubscription
, una clase interna de SubmissionPublisher
(fuente vinculada anteriormente), estableció una cerca completa en la línea 1079 (función growAndAdd
; ya que el sitio web vinculado no admite identificadores de fragmentos, solo CTRL + F para ello ) Sin embargo, no está claro para mí para qué sirve.
plain -> opaque -> release/acquire -> volatile (sequential consistency)
.