スレッドtAがtB.join()を呼び出すと、その原因はtBの終了またはtA自体の中断を待つだけでなく、tBの最後のステートメントとtAスレッドのtB.join()の後の次のステートメントとの間に発生前の関係を作成します。
スレッド内のすべてのアクションは、他のスレッドがそのスレッドのjoin()から正常に戻る前に発生します。
プログラムを意味します
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);
}
}
常に印刷する
>> 1111111111111111111111111 ...
しかしプログラム
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);
}
}
印刷できるだけでなく
>> 0000000000 ... 000000111111111111111111111111 ...
だが
>> 00000000000000000000000000000000000000000000 ...
常に「0」のみ。
Javaメモリモデルでは、heppens-beforeの関係なしに、スレッドBからメインスレッドに「sharedVar」の新しい値を「転送」する必要がないため(スレッド開始、スレッド結合、「synchonized」キーワードの使用、AtomicXXX変数の使用など)。