Dupliqué possible: strong>
Sécurité du fil en classe Java P>Je lis java simultancy dans la pratique em>, et je suis venu à un exemple qui me puzzle moi. p>
Les auteurs affirment que cette classe n'est pas threadsafe p >
xxx pré> et ils indiquent également que la synchronisation d'une seule méthode (le setter par exemple) ne le ferait pas; Vous devez syncroniser les deux. P>
Ma question est la suivante: pourquoi? Ne synchroniserait pas le setter juste faire? P> blockquote>
4 Réponses :
Java a un événement avant / se passe après le modèle de mémoire. Il doit y avoir une certaine construction concurrente commune (par exemple, bloc / méthode synchronisée, verrouillage, volatil, atomique) sur le chemin d'écriture et le chemin de lecture pour déclencher ce comportement. P>
Si vous synchronisez les deux méthodes, vous créez un verrou sur l'objet entier qui sera partagé à la fois par les threads de lecture et d'écriture. La JVM garantira que toutes les modifications qui se produisent sur le fil d'écriture qui se produisent avant de quitter la méthode de consigne (synchronisée) seront visibles pour toutes les filetages de lecture après avoir entré la méthode de Geint (synchronisée). Le JVM insérera les barrières de mémoire nécessaires pour que cela se produise. P>
Si seule la méthode d'écriture est synchronisée, les modifications apportées à l'objet peuvent ne pas être visibles pour aucun fil de lecture. En effet, aucun point sur le chemin de lecture que le JVM peut utiliser pour s'assurer que la mémoire visible du thread de lecture (cache, etc.) est en ligne avec le fil d'écriture. Rendre la méthode de getint synchronisée fournirait cela. P>
REMARQUE: Spécifiquement, dans ce cas, la volatille "numéro" donnerait le comportement correct car la lecture / écriture volatile fournit également le même comportement de visibilité de la mémoire dans la JVM et l'action à l'intérieur de la méthode de seint n'est qu'une affectation. < / p>
Ceci est une ligne de commentaire typique.
Rendre le champ 'Number' volatils ne rend pas l'opération d'affectation atomique. La méthode doit être synchronisée
Expliquez le scénario d'échec réel impliqué si le champ est volatil et que la méthode n'est pas synchronisée.
parce que numéro code> n'est pas volatil et
getint () code> n'est pas synchronisé,
getint () code> peut renvoyer des valeurs obsolètes. Pour plus d'informations, lisez sur le modèle de mémoire Java. P>
Désolé, la réponse est au moins incomplète et l'indice inutile à mes yeux. Il a demandé une explication sur un problème concret (-1)
Il est expliqué dans le livre avant l'échantillon (page 35): p>
"Synchronisation Seuls Setter ne serait pas suffisant: les threads appelant obtenaient d'être en mesure de voir des valeurs obsolètes." P>
Données obsolètes: Lorsque le thread de lecteur examine prêts, il peut voir une valeur obsolète. Sauf que la synchronisation n'est utilisée
Je suis B> Lecture du livre, affirmant que "il sera capable de voir des valeurs rassis" ne suffit pas, je veux des fondements.
Donc, vous ne croyez pas, qu'il y a là la possibilité de voir de valeur obsolète si le getter n'est pas synchronisé et que vous souhaitez prouver pour cela, ou que voulez-vous dire?
Je veux comprendre pourquoi. La raison en est que les threads conservent les valeurs mises en cache locales des variables et que les lectures risquent de ne pas rincer le cache. Si le cache n'était pas là, cela n'aurait pas d'importance s'il y avait des méthodes synchronisées ou non (les deux opérations sont atomiques)
Si vous ne synchronisez que la méthode Setter, vous ne pouvez garantir que l'attribut ne serait pas modifié de manière incorrecte, mais vous ne pouvez pas être sûr de la valeur obsolète lorsque vous essayez de lire la variable. p>
En fait, c'est la subtilité différente.