Tout en essayant de comprendre comment SubmissionPublisher
( code source dans Java SE 10, OpenJDK | docs ), une nouvelle classe ajoutée à Java SE dans la version 9, a été implémentée, je suis tombé sur quelques appels d'API dont VarHandle
je n'étais pas au courant auparavant:
fullFence
, acquireFence
, releaseFence
, loadLoadFence
Et storeStoreFence
.
Après avoir fait quelques recherches, en particulier en ce qui concerne le concept de barrières / clôtures de mémoire (j'en ai entendu parler auparavant, oui; mais je ne les ai jamais utilisées, donc je ne connaissais pas bien leur sémantique), je pense avoir une compréhension de base de ce à quoi elles servent. . Néanmoins, comme mes questions pourraient découler d'une idée fausse, je veux m'assurer d'avoir bien compris en premier lieu:
Les barrières mémoire réorganisent les contraintes concernant les opérations de lecture et d'écriture.
Les barrières mémoire peuvent être classées en deux catégories principales: les barrières mémoire unidirectionnelles et bidirectionnelles, selon qu'elles définissent des contraintes sur les lectures ou les écritures ou sur les deux.
C ++ prend en charge une variété de barrières de mémoire , cependant, celles-ci ne correspondent pas à celles fournies par
VarHandle
. Cependant, certaines des barrières de mémoire disponiblesVarHandle
fournir des effets de commande qui sont compatibles à leurs barrières de mémoire C ++ correspondant.#fullFence
est compatible avecatomic_thread_fence(memory_order_seq_cst)
#acquireFence
est compatible avecatomic_thread_fence(memory_order_acquire)
#releaseFence
est compatible avecatomic_thread_fence(memory_order_release)
#loadLoadFence
et#storeStoreFence
n'ont pas de contrepartie C ++ compatible
Le mot compatible semble vraiment important ici car la sémantique diffère clairement en ce qui concerne les détails. Par exemple, toutes les barrières C ++ sont bidirectionnelles, contrairement aux barrières Java (nécessairement).
- La plupart des barrières mémoire ont également des effets de synchronisation. Celles-ci dépendent en particulier du type de barrière utilisé et des instructions de barrière précédemment exécutées dans d'autres threads. Comme les implications complètes d'une instruction de barrière sont spécifiques au matériel, je m'en tiendrai aux barrières de niveau supérieur (C ++). En C ++, par exemple, les modifications apportées avant une instruction de barrière de libération sont visibles par un thread exécutant une instruction de barrière d' acquisition .
Mes hypothèses sont-elles correctes? Si oui, mes questions résultantes sont:
Les barrières de mémoire disponibles
VarHandle
provoquent-elles une sorte de synchronisation de la mémoire?Qu'elles provoquent ou non une synchronisation de la mémoire, à quoi peuvent servir les contraintes de réorganisation en Java? Le modèle de mémoire Java donne déjà des garanties très solides concernant l'ordre lorsque des champs volatils, des verrous ou des
VarHandle
opérations similaires#compareAndSet
sont impliqués.
Dans le cas où vous cherchez un exemple: ce qui précède BufferedSubscription
, une classe interne de SubmissionPublisher
(source liée ci-dessus), a établi une clôture complète dans la ligne 1079 (fonction growAndAdd
; car le site Web lié ne prend pas en charge les identificateurs de fragment, juste CTRL + F pour cela ). Cependant, je ne sais pas à quoi cela sert.
plain -> opaque -> release/acquire -> volatile (sequential consistency)
.