2012-12-03 34 views
16

Gần đây tôi đã nghe trong một cuộc nói chuyện rằng ghi vào một biến động kích hoạt một rào cản bộ nhớ cho mỗi biến mà luồng đã ghi vào. Điều đó có thực sự chính xác không? Từ JLS, có vẻ như chỉ có biến liên quan bị xóa sổ, nhưng không phải là những biến khác. Có ai biết điều gì thực sự đúng không? Tôi có thể chỉ cho tôi một vị trí cụ thể trong JLS không?Là viết thư cho một rào cản bộ nhớ dễ bay hơi trong Java

+1

Giải thích của tôi về JLS đồng ý với bạn. – NPE

+1

có thể trùng lặp của [Biến dễ bay hơi và các biến khác] (http://stackoverflow.com/questions/12438464/volatile-variables-and-other-variables) – assylias

+0

Khi câu trả lời làm rõ, nó không chỉ là biến được khai báo là dễ bay hơi mà tất cả các bài viết đã xảy ra trước khi viết dễ bay hơi. – sjlee

Trả lời

1

Các tài liệu tham khảo để Volatile variables and other variables là đúng. Tôi đã không nhận ra rằng sự chuyển đổi của xảy ra-trước là cái gì đó phải được thực hiện bởi máy ảo, không phải cái gì đó theo sau định nghĩa. Tôi vẫn còn bối rối vì sao một cái gì đó có hậu quả sâu xa như vậy không được nói rõ ràng nhưng thực ra là một hệ quả từ một định nghĩa nào đó. Để quấn nó lên: Giả sử bạn có 4 hành động như thế này:.

thread1  thread2 
a1 
a2 
       a3 
       a4 

nơi a2 là một ghi vào một v biến dễ bay hơi và a3 là một đọc so với cùng v biến dễ bay hơi Nó sau từ definiton của xảy ra -before (hb) mà hb (a1, a2) và hb (a3, a4). Ngoài ra, đối với các chất bay hơi chúng ta có hb (a2, a3). Nó theo sau từ sự chuyển tiếp yêu cầu của hb mà hb (a1, a3). Vì vậy, viết và đọc tiếp theo của biến v biến động hoạt động như một rào cản bộ nhớ.

16

Có, nó sẽ bắt đầu một rào cản. Bạn có thể đọc thêm here. Có 4 loại, LoadLoad LoadStore StoreStore StoreLoad.

Theo như câu hỏi của bạn

Từ JLS, dường như chỉ biến liên quan bị đỏ mặt ra, nhưng không phải người khác. Có ai biết điều gì thực sự đúng không?

Tất cả các ghi xảy ra trước khi một cửa sổ dễ bay hơi được hiển thị bởi bất kỳ chủ đề nào khác có vị ngữ mà các luồng khác tải cửa hàng mới này. Tuy nhiên, việc viết xảy ra trước khi một tải biến động có thể hoặc không thể nhìn thấy bởi các luồng khác nếu chúng không tải giá trị mới.

Đối với một ví dụ thực tế

volatile int a =0; 
int b = 0; 

Thread-1 
b = 10; 
a = 3; 

Thread-2 
if(a == 0){ 
    // b can b 10 or 0 
} 
if(a == 3){ 
    // b is guaranteed to be 10 (according to the JMM) 
} 
+1

+1 * "với vị ngữ mà các chủ đề khác tải cửa hàng mới này" * – assylias

+4

Tôi nghĩ rằng ví dụ của bạn là sai. Thread-2 không cần so sánh 'a' với 3 để xem giá trị mới của' b', nó đủ để đọc 'a'. Vì vậy, ngay sau dòng đầu tiên, Thread-2 được đảm bảo để xem 'b' bằng 10 (trong tất cả các nhánh). Tuy nhiên, luồng thứ ba không bao giờ đọc 'a' không được bảo đảm để xem giá trị mới của' b'. –

+11

@PhilippWendler Tôi nghĩ rằng vấn đề là: nếu a == 0, thì ghi 'a = 3' chưa xảy ra và b có thể là bất cứ thứ gì, kể cả 10. nếu a == 3, thì ghi' a = 3' đã xảy ra và bạn được đảm bảo có b == 10. – assylias

Các vấn đề liên quan