Quan hệ nhân quả trong JMM có vẻ là phần khó hiểu nhất của nó. Tôi có một số câu hỏi liên quan đến quan hệ nhân quả JMM và hành vi được phép trong các chương trình đồng thời.Tại sao hành vi này được phép trong Mô hình bộ nhớ Java?
Như tôi đã biết, JMM hiện tại luôn cấm các vòng nhân quả. (Tôi có phải không?)
Bây giờ, theo các tài liệu JSR-133, trang 24, Fig.16, chúng ta có một ví dụ trong đó:
Ban đầu x = y = 0
Chủ đề 1:
r3 = x;
if (r3 == 0)
x = 42;
r1 = x;
y = r1;
Chủ đề 2:
r2 = y;
x = r2;
Trực quan, r1 = r2 = r3 = 42
dường như không thể. Tuy nhiên, nó không chỉ được đề cập ở mức có thể, mà còn được 'cho phép' trong JMM.
Đối với khả năng, giải thích từ tài liệu mà tôi không hiểu là:
Một trình biên dịch có thể xác định rằng các giá trị duy nhất từng được gán cho
x
là 0 và 42. Từ đó, trình biên dịch có thể suy luận rằng, tại điểm nơi chúng tôi thực hiệnr1 = x
, chúng tôi vừa thực hiện ghi 42 đếnx
hoặc chúng tôi vừa đọcx
và thấy giá trị 42. Trong cả hai trường hợp, nó sẽ là hợp pháp để đọcx
để xem giá trị 42. Sau đó, nó có thể thay đổir1 = x
thànhr1 = 42
; điều này sẽ cho phépy = r1
được chuyển thànhy = 42
và được thực hiện trước đó, dẫn đến hành vi được đề cập. Trong trường hợp này, ghi sốy
được cam kết trước tiên.
Câu hỏi của tôi là, loại tối ưu hóa trình biên dịch nào thực sự? (Tôi là trình biên dịch-dốt nát.) Vì 42 được viết chỉ có điều kiện, khi câu lệnh if
được thỏa mãn, làm thế nào trình biên dịch có thể quyết định đi bằng văn bản của x
? Thứ hai, ngay cả khi trình biên dịch thực hiện tối ưu hóa đầu cơ này, và cam kết y = 42
và thì cuối cùng làm cho r3 = 42
, không phải là nó vi phạm vòng lặp nhân quả, vì không còn nguyên nhân và sự khác biệt có hiệu lực bây giờ không? Không.
Trong thực tế, có một ví dụ trong cùng một tài liệu (trang 15, Hình 7) trong đó vòng lặp nhân quả tương tự được đề cập là không thể chấp nhận.
Vậy cách thực hiện lệnh này là hợp pháp trong JMM?
@Alexei Điều đó giải thích một số điều đó. Nhưng, không nên trình biên dịch làm cho nó 'r3 = 0' thay vì 'r3 = 42'? Hoặc họ chỉ cho thấy 'một khả năng'! – gaganbm
Trình biên dịch không tạo ra 'r3 = 42', nó chỉ để lại' r3 = x' nguyên vẹn. Tối ưu hóa trình biên dịch không phải lúc nào cũng được thực hiện ở độ sâu tối đa. Nếu có khả năng tối thiểu là việc tối ưu hóa có thể vi phạm chính xác, nó bị bỏ rơi. Trong mã đã cho, không có trường hợp như vậy, nhưng chúng có thể xuất hiện nếu một số mã khác có mặt. Bên cạnh đó, trình biên dịch có thể quyết định rằng 'r3 = 0' có cùng giá với' r3 = x'. –