Dans le livre Java Concurrency In Practice, on nous dit plusieurs fois que les instructions de notre programme peuvent être réorganisées, soit par le compilateur, par la JVM lors de l'exécution, soit même par le processeur. Donc nous devons supposer que le programme exécuté n'aura pas ses instructions exécutées exactement dans le même ordre que ce que nous avons spécifié dans le code source.
Cependant, le dernier chapitre traitant de Java Memory Model fournit une liste des règles occur-before indiquant l'ordre des instructions qui sont préservées par la JVM. La première de ces règles est:
Je crois que "l'ordre des programmes" fait référence au code source.
Ma question: en supposant cette règle, je me demande quelle instruction peut être réorganisée.
"Action" est définie comme suit:
Le modèle de mémoire Java Java est spécifié en termes d’actions, qui incluent les lectures et les écritures sur les variables, les verrous et les déverrouillages des moniteurs, ainsi que le démarrage et la jonction avec des threads. Le JMM définit un ordre partiel appelé se produit avant sur toutes les actions du programme. Pour garantir que le thread exécutant l'action B puisse voir les résultats de l'action A (que A et B se produisent ou non dans différents threads), il doit y avoir un événement avant la relation entre A et B. En l'absence d'un événement avant de passer une commande entre deux opérations, la JVM est libre de les réorganiser à sa guise.
Les autres règles de commande mentionnées sont:
Le point clé de la règle d'ordre du programme est: dans un fil.
Imaginez ce programme simple (toutes les variables initialement 0):
T1:
x = 5;
y = 6;
T2:
if (y == 6) System.out.println(x);
Du point de vue de T1, une exécution doit être cohérente avec l'affectation de y après x (ordre du programme). Cependant, du point de vue de T2, cela ne doit pas être le cas et T2 peut imprimer 0.
T1 est en fait autorisé à assigner y en premier car les 2 affectations sont indépendantes et leur permutation n'affecte pas l'exécution de T1.
Avec une synchronisation appropriée, T2 imprimera toujours 5 ou rien.
[~ # ~] modifier [~ # ~]
Vous semblez mal interpréter le sens de l'ordre des programmes. La règle d'ordre du programme se résume à :
Si
x
ety
sont des actions du même thread et quex
précèdey
dans l'ordre du programme, alorshb(x, y)
(iex
arrive-avanty
).
arrive-avant a une signification très spécifique dans le JMM. En particulier, cela signifie pas signifie que y=6
Doit être postérieur à x=5
En T1 du point de vue de l'horloge murale. Cela signifie seulement que la séquence d'actions exécutées par T1 doit être cohérente avec cet ordre. Vous pouvez également vous référer à JLS 17.4.5 :
Il est à noter que la présence d'une relation passe-avant entre deux actions n'implique pas nécessairement qu'elles doivent se dérouler dans cet ordre dans une implémentation . Si la réorganisation produit des résultats compatibles avec une exécution légale, elle n'est pas illégale.
Dans l'exemple que j'ai donné ci-dessus, vous conviendrez que du point de vue de T1 (c'est-à-dire dans un programme à thread unique), x=5;y=6;
Est cohérent avec y=6;x=5;
Puisque vous ne lisez pas les valeurs. Une déclaration sur la ligne suivante est garantie, en T1, pour voir ces 2 actions, quel que soit l'ordre dans lequel elles ont été effectuées.