Khi luồng tA gọi tB.join (), các nguyên nhân của nó không chỉ chờ tB chết hoặc tA bị gián đoạn mà còn tạo ra mối quan hệ xảy ra trước câu lệnh cuối trong tB và câu lệnh tiếp theo sau tB.join () trong luồng tA.
Tất cả các hành động trong một luồng xảy ra - trước khi bất kỳ luồng nào khác trả về thành công từ một phép nối () trên luồng đó.
Nó có nghĩa là chương trình
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);
}
}
Luôn in
>> 1111111111111111111111111 ...
Nhưng chương trình
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);
}
}
Có thể in không chỉ
>> 0000000000 ... 000000111111111111111111111111 ...
Nhưng
>> 00000000000000000000000000000000000000000000 ...
Luôn luôn chỉ '0'.
Bởi vì Mô hình bộ nhớ Java không yêu cầu 'chuyển' giá trị mới của 'sharedVar' từ luồngB sang luồng chính mà không có mối quan hệ trước gan (bắt đầu luồng, nối chuỗi, sử dụng từ khóa 'đồng bộ hóa', sử dụng biến AtomicXXX, v.v.).