Giả sử có một lớp như thế này:Java Memory Model: Trộn không đồng bộ và đồng bộ
public void MyClass {
private boolean someoneTouchedMeWhenIWasWorking;
public void process() {
someoneTouchedMeWhenIWasWorking = false;
doStuff();
synchronized(this) {
if (someoneTouchedMeWhenIWasWorking) {
System.out.println("Hey!");
}
}
}
synchronized public void touch() {
someoneTouchedMeWhenIWasWorking = true;
}
}
Một chủ đề kêu gọi process
, một cuộc gọi touch
. Lưu ý cách process
xóa cờ mà không đồng bộ hóa khi bắt đầu.
Với mô hình bộ nhớ Java, có thể nào thread chạy process
sẽ thấy tác dụng của ghi địa phương, không đồng bộ, mặc dù touch
xảy ra sau?
Nghĩa là, nếu các chủ đề thực hiện theo thứ tự này:
T1: someoneTouchedMeWhenIWasWorking = false; // Unsynchronized
T2: someoneTouchedMeWhenIWasWorking = true; // Synchronized
T1: if (someoneTouchedMeWhenIWasWorking) // Synchronized
... là nó bao giờ có thể là T1 sẽ thấy giá trị từ bộ nhớ cache cục bộ của nó? Nó có thể tuôn ra những gì nó có để bộ nhớ đầu tiên (ghi đè bất cứ điều gì T2 đã viết), và tải lại giá trị đó từ bộ nhớ?
Có cần phải đồng bộ hóa ghi đầu tiên hoặc biến biến động không?
Tôi thực sự đánh giá cao nếu câu trả lời được hỗ trợ bởi tài liệu hoặc một số nguồn đáng kính.
Câu hỏi không phải là về cách làm cho mã an toàn, nhưng nó có an toàn không? – icza
Khối đồng bộ trong quá trình() đảm bảo rằng giá trị mới nhất từ bộ nhớ chính được chọn. Do đó mã là an toàn vì nó được. –