スレッド 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 メモリ モデルでは、「sharedVar」の新しい値をスレッド B からメイン スレッドに heppens-before 関係 (スレッド開始、スレッド結合、「synchonized」キーワードの使用、AtomicXXX 変数の使用など) なしで「転送」する必要がないためです。