当线程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关系的情况下(线程启动,线程连接,使用'synchonized'关键字,使用AtomicXXX变量等),无需将'sharedVar'的新值从threadB转移到主线程。