Lorsque le thread tA appelle tB.join(), il n'attend pas seulement que tB meure ou que tA soit lui-même interrompu, mais il crée une relation "happens-before" entre la dernière déclaration de tB et la déclaration suivante après tB.join() dans le thread tA.
Toutes les actions d'un thread se produisent avant qu'un autre thread ne revienne avec succès d'un join() sur ce thread.
Cela signifie que le programme
class App {
// shared, not synchronized variable = bad practice
static int sharedVar = 0;
public static void main(String[] args) throws Exception {
Thread threadB = new Thread(() -> {sharedVar = 1;});
threadB.start();
threadB.join();
while (true)
System.out.print(sharedVar);
}
}
Toujours imprimer
>> 1111111111111111111111111 ...
Mais le programme
class App {
// shared, not synchronized variable = bad practice
static int sharedVar = 0;
public static void main(String[] args) throws Exception {
Thread threadB = new Thread(() -> {sharedVar = 1;});
threadB.start();
// threadB.join(); COMMENT JOIN
while (true)
System.out.print(sharedVar);
}
}
Peut imprimer non seulement
>> 0000000000 ... 000000111111111111111111111111 ...
Mais
>> 00000000000000000000000000000000000000000000 ...
Toujours uniquement '0'.
Parce que le modèle de mémoire Java n'exige pas le "transfert" de la nouvelle valeur de "sharedVar" du threadB au thread principal sans relation heppens-before (démarrage du thread, thread join, utilisation du mot clé "synchonized", utilisation des variables AtomicXXX, etc).