dans une récente Réponse J'ai suggéré qu'il soit possible d'atteindre la fonctionnalité de Cela m'a fait penser que je n'ai pas besoin de bloquer sur l'objet contenant, j'ai juste besoin d'obtenir une barrière de mémoire. Comme volatile code> Par
Synchronisation code> sur l'objet contenant la variable, nous devons être code> volatile code> (Acheter n'a pas accès à la variable dans le code). P>
synchronisé code> atteint la synchronisation forte> forte> et strong> une barrière mémoire, si tout ce dont j'ai besoin est la barrière mémoire (comme dans ce cas) serait-elle réellement meilleure Pour utiliser
synchronisé (nouvel objet ()) code> pour atteindre ma barrière de mémoire
3 Réponses :
serait-il vraiment préférable d'utiliser
synchronisé (nouvel objet ()) code> pour atteindre mon barrière de mémoire et assurez-vous que le verrou n'est jamais allégé? P> blockQuote>
nop. Le JVM peut facilement prouver que ce verrouillage ne peut pas être accessible par deux threads (puisqu'il s'agit d'une variable de thread-locale) et de la transformer presque certainement en un non-op, c'est-à-dire complètement supprimer le
synchronisé code> déclaration. p>
Alors, comment puis-je obtenir une barrière de mémoire comme volatile code> sans régler la variable réelle
volatile code> tout en minimisant / éliminant la conflit de verrouillage?
@OldcurMudgeon j'ai vu quelque chose dans le paquet Sun.Misc, mais pas sûr si c'était dans JDK 7 ou 8 (quelque chose comme: non sécurisé.load / non sécurisé.store) - ne peut pas la creuser maintenant.
Comme expliqué ici: http: / /www.cs.umd.edu/~pugh/java/MemoryModel/jsr-133-faq.html#synchronisation Synchronisé (nouvel objet ()) est considéré comme un noop et peut être entièrement supprimé par le compilateur. Vous n'obtiendrez pas de barrière de mémoire. P>
Qu'est-ce qui réaliserait ce que j'essaie d'obtenir - une barrière de mémoire sans lutter contre la serrure?
En plus du très bon point de @ Assylias, considérons également que Quoi qu'il en soit, si vous vous souciez de la spécification, mais uniquement sur les implémentations du monde réel, alors pourquoi ne pas introduire votre propre variable code> volatile code> et simplement écrivez-y quand vous voulez une barrière de mémoire ? C'est sans importance quel em> synchronisé code> n'atteint pas une barrière de mémoire par des spécifications. Ce n'est que le cas où il s'agit de la manière dont il est mis en œuvre sur les architectures typiques de la mémoire CPU d'aujourd'hui. La spécification ne garantit que ce qui se passe lorsque deux threads acquièrent le même verrou. P>
volatile code> vous écrivez, tant que nous parlons d'un ensemble d'architectures contraint qui est impliqué par votre
synchronisé (nouvel objet () ) code> idée. p>
Je pense que c'est le point critique que je manque - la barrière ne s'applique qu'à tous les partampis de l'objet de verrouillage spécifique. Bien que la plupart des discussions sur ce sujet mentionnent des caches de rinçage, il serait tout à fait possible pour une implémentation de simplement pousser les valeurs mises en cache d'un processeur à une autre.
Dans la question, Asker voulait appeler un Set ... code> méthode d'un objet qu'ils ne disposent pas de contrôle de plusieurs threads. La variable ne peut pas être faite
volatile code>.
Oui, je m'attends à ce que cela se produise comme le nombre d'unités d'exécution (cœurs ou autre) grandit. Dans des systèmes massivement parallèles, il n'y a pas de cohérence cache, et je pense que le grand public est fermement installé sur cette route maintenant.
Malheureusement, il n'y a pas de primitive Java qui a la sémantique exacte de la "barrière mémoire".
Après votre modification - suggérez-vous que l'accès à une variable volatile toute B> invalidera les valeurs mises en cache toutes b>? J'aurais pensé que que la variable b> serait rinçue dans ce cas.
Ce n'est certainement pas seulement celui-là, et c'est par spécification: tout accessible i> de ce VaR (si elle est dactylographiée, bien sûr) doit également être rinçue. C'était un motivateur clé de la grande réécriture du modèle de mémoire Java pour Java 1.5.
Pardonnez-moi, je pense que c'est en fait toutes les actions du fil qui a fait l'écriture sont visibles au fil qui fait la lecture i> --- qui est très proche d'une barrière de mémoire réelle!
Voir aussi: Stackoverflow .com / questions / 37142411 / ...