34 votes

Modèle de mémoire Java - quelqu'un peut-il l'expliquer ?

Pendant des années et des années, j'ai essayé de comprendre la partie de la spécification Java qui traite du modèle de mémoire et de la concurrence. Je dois admettre que j'ai échoué lamentablement. Oui' je comprends les verrous et "synchronisé" et wait() et notify(). Et je peux très bien les utiliser, merci. J'ai même une vague idée de ce que fait "volatile". Mais tout cela n'est pas issu des spécifications du langage - plutôt de l'expérience générale.

Voici deux exemples de questions que je pose. Je ne suis pas tellement intéressé par des réponses particulières, mais j'ai besoin de comprendre comment les réponses sont dérivées de la spécification (ou peut-être comment je conclus que la spécification n'a pas de réponse).

  • Que fait "volatile", exactement ?
  • Les écritures sur les variables sont-elles atomiques ? Cela dépend-il du type de la variable ?

35voto

Jon Skeet Points 692016

Je ne vais pas tenter de répondre à vos questions ici - je vais plutôt vous rediriger vers le livre que j'ai vu recommandé pour des conseils sur ce sujet : Java Concurrency en pratique .

Un mot d'avertissement : s'il y a sont réponses ici, attendez-vous à ce que beaucoup d'entre elles soient fausses. L'une des raisons pour lesquelles je ne vais pas poster les détails est que je suis presque sûr que Je se trompent au moins sur certains points. Je ne veux absolument pas manquer de respect à la communauté en disant que les chances que tous ceux qui pensent pouvoir répondre à cette question aient suffisamment de rigueur pour y parvenir sont pratiquement nulles. (Joe Duffy a récemment trouvé une partie du modèle de mémoire de .NET qui l'a surpris. S'il peut se tromper, les mortels comme nous le peuvent aussi).


Je vais vous donner un aperçu d'un seul aspect, car il est souvent mal compris :

Il y a une différence entre la volatilité et l'atomicité. Les gens pensent souvent qu'une écriture atomique est volatile (c'est-à-dire que vous n'avez pas besoin de vous soucier du modèle de mémoire si l'écriture est atomique). Ce n'est pas le cas.

La volatilité consiste à savoir si un thread effectuant une lecture (logiquement, dans le code source) "verra" les modifications apportées par un autre thread.

L'atomicité consiste à savoir s'il y a une chance que si un changement es vu, seule une partie du changement sera visible.

Par exemple, prenons l'écriture dans un champ de nombres entiers. Cette écriture est garantie comme étant atomique, mais pas volatile. Cela signifie que si nous avons (à partir de foo.x = 0) :

Thread 1: foo.x = 257;
Thread 2: int y = foo.x;

Il est possible pour y doit être 0 ou 257. Ce ne sera pas une autre valeur (par exemple 256 ou 1) en raison de la contrainte d'atomicité. Cependant, même si vous savez que dans le "wall time", le code du thread 2 a été exécuté après le code du thread 1, il peut y avoir une mise en cache bizarre, des accès mémoire qui "bougent", etc. En rendant la variable x volatile va régler ce problème.

Je laisse le reste aux vrais experts.

14voto

Michael Borgwardt Points 181658
  • non volatile Les variables peuvent être mises en cache de manière locale, de sorte que différents threads peuvent voir différentes valeurs au même moment ; volatile empêche cela ( source )
  • Les écritures dans les variables de 32 bits ou moins sont garanties comme étant atomiques ( sous-entendu ici ) ; ce n'est pas le cas pour long y double bien que les JVM 64 bits les implémentent probablement comme des opérations atomiques.

7voto

Filip Korling Points 559

Je n'essaierai pas d'expliquer ces questions ici, mais je vous renvoie plutôt à l'excellent livre de Brian Goetz sur le sujet.

Le livre s'intitule "Java Concurrency in Practice" et peut être consulté à l'adresse suivante Amazon ou tout autre magasin bien trié de littérature informatique.

4voto

Yuval Adam Points 59423

Voici un bon lien qui peut vous donner des informations un peu plus approfondies :

http://www.cs.umd.edu/~pugh/java/memoryModel/jsr-133-faq.html

0 votes

Merci pour le lien ! Il ne remplace pas un livre (que je vais me procurer), mais il m'a donné un aperçu : j'ai l'habitude de penser à la synchronisation, et le modèle de mémoire est plus concerné par le réordonnancement. Je dois apprendre à distinguer les deux, et à penser à la dernière.

4voto

FoxyBOA Points 3334

J'ai récemment trouvé un excellent article qui expliquent le volatile comme :

Tout d'abord, vous devez comprendre un peu le modèle de mémoire Java. Au fil des ans, j'ai eu un peu de mal à l'expliquer brièvement et correctement. Aujourd'hui, le meilleur moyen auquel je pense pour le décrire est de l'imaginer de cette façon :

  • Chaque thread en Java se déroule dans un espace mémoire distinct (c'est clairement faux, alors soyez indulgent avec moi sur ce point).

  • Vous devez utiliser des mécanismes spéciaux pour garantir que la communication s'effectue entre ces threads, comme vous le feriez sur un système de passage de messages.

  • Les écritures en mémoire qui se produisent dans un thread peuvent "fuir" et être vues par un autre thread, mais cela n'est en aucun cas garanti. Sans communication explicite, vous ne pouvez pas garantir quelles écritures seront vues par les autres threads, ni même l'ordre dans lequel elles seront vues.

Le modificateur volatile de Java est un exemple de mécanisme spécial permettant de garantir que la communication s'effectue entre les threads. Lorsqu'un thread écrit dans une variable volatile et qu'un autre thread voit cette écriture, le premier thread informe le second de tout le contenu de la mémoire jusqu'à ce qu'il effectue l'écriture dans cette variable volatile.

Liens supplémentaires : http://jeremymanson.blogspot.com/2008/11/what-volatile-means-in-java.html http://www.javaperformancetuning.com/news/qotm030.shtml

1 votes

Ce n'est pas N, c'est N+1 ! Voir ma propre réponse :)

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