50 votes

L'écriture d'une référence est atomique sur les VMs 64bit

Le modèle de mémoire java impose que l'écriture d'un fichier int est atomique : C'est-à-dire que si vous y écrivez une valeur (constituée de 4 octets) dans un thread et que vous la lisez dans un autre, vous obtiendrez tous les octets ou aucun, mais jamais 2 nouveaux octets et 2 anciens octets ou autre.

Ceci n'est pas garanti pour long . Ici, l'écriture 0x1122334455667788 à une variable contenant 0 avant pourrait rés rés rés rés rés rés rés rés rés rés rés rés rés rés rés rés rés rés rés rés rés rés rés rés rés rés rés rés rés rés rés rés rés rés rés d'un autre fil de lecture 0x112233440000000 o 0x0000000055667788 .

Aujourd'hui, la spécification n'impose pas que les références d'objets soient de taille int ou longue. Pour des raisons de sécurité de type, je soupçonne qu'elles sont garanties d'être écrites de manière atomique, mais sur une VM 64 bits, ces références pourraient très bien être des valeurs 64 bits (simplement des adresses mémoire).

Maintenant, voici mes questions :

  • Existe-t-il des spécifications de modèles de mémoire couvrant ce point (que je n'ai pas trouvées) ?
  • Les écritures longues sont-elles suspectées d'être atomiques sur les VM 64 bits ?
  • Les VM sont-elles obligées de mapper les références en 32 bits ?

Regards, Steffen

2 votes

@Steffen Heil : pinaillage mais notez que toutes les références ne sont pas 64 bits en interne même sur une VM 64 bits (en raison de la quantité incroyable de déchets que les références 64 bits génèrent). Les VM modernes utilisent la compression des pointeurs/références appelée "CompressedOops" : wikis.sun.com/affichage/HotSpotInternals/CompressedOops Donc je ne suis pas en désaccord avec le fait qu'ils pourrait être une valeur 64 bits, mais ils ne le sont souvent pas (ce qui ne change pas grand-chose à la réponse que Dirk a postée).

61voto

Dirk Points 17809

Références de lecture/écriture toujours atomiques

Voir JLS section 17.7 : Traitement non atomique de double et long

Dans le cadre du modèle de mémoire du langage de programmation Java, un fichier une seule écriture dans une valeur longue ou double non volatile est traitée comme deux deux écritures distinctes : une sur chaque moitié de 32 bits. Cela peut aboutir à une situation où un thread voit les 32 premiers bits d'une valeur de 64 bits lors d'une une écriture, et les 32 bits suivants d'une autre écriture.

Les écritures et lectures de valeurs longues et doubles volatiles sont toujours atomiques.

Les écritures et les lectures de références sont toujours atomiques, peu importe qu'elles soient implémentées en tant que valeurs 32 bits ou 64 bits.

Certaines implémentations peuvent trouver pratique de diviser une simple action d'écriture sur une valeur longue ou double de 64 bits en deux actions d'écriture sur des valeurs adjacentes de 32 bits. valeurs 32 bits adjacentes. Pour des raisons d'efficacité, ce comportement est spécifique à l'implémentation ; une implémentation de la machine virtuelle de Java est libre d'effectuer des écritures sur des valeurs longues et doubles de manière atomique ou en deux parties. deux parties.

Les implémentations de la machine virtuelle Java sont encouragées à éviter de le fractionnement des valeurs 64 bits lorsque cela est possible. Les programmeurs sont encouragés à déclarer les valeurs 64 bits partagées comme volatiles ou synchroniser leurs programmes programmes afin d'éviter d'éventuelles complications.

(C'est nous qui soulignons)

AtomicReference

Si vous souhaitez coordonner les anciennes et les nouvelles valeurs, ou si vous voulez effets spécifiques sur la mémoire utiliser la classe AtomicReference .

Par exemple, AtomicReference::getAndSet retourne l'ancienne valeur tout en fixant la nouvelle de manière atomique, éliminant toute chance qu'un autre thread soit intervenu entre les deux étapes. Utilise volatile sémantique de la mémoire .

0 votes

Ok, j'ai encore raté le point dans les spécifications. Il me semble que je suis trop fatigué et que je devrais dormir au lieu de poser des questions... Merci pour l'indication. (ENCORE UNE FOIS)

4 votes

Si "les écritures et les lectures de références sont toujours atomiques, qu'elles soient implémentées en tant que valeurs 32 ou 64 bits", pourquoi avons-nous la classe AtomicReference ( docs.oracle.com/javase/7/docs/api/java/util/concurrent/atomic/ ) ? Seulement à cause des méthodes getAndSet/compareAndSet ?

0 votes

Ne pas voir les valeurs de référence déchirées n'est qu'une partie du problème. Le site AtomicReference existe principalement pour son API de synchronisation (l compareAndSet auquel vous avez fait allusion), @mc.Android.developer, et il n'y a pas de "seulement" ici. C'est en fait la partie importante.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X