2014-04-15 19 views
5

Rất nổi tiếng trong số các lập trình viên Java để khóa kiểm tra kép hoạt động chính xác, biến phải được khai báo volatile và đồng bộ hóa việc khởi tạo đối tượng là không đủ.Có phải `biến động 'bắt buộc đối với khóa được kiểm tra kép trong Java nhưng không phải là C#?

Nhận thức có lẽ chủ yếu là do ngữ nghĩa của từ khóa volatile đã được thay đổi trong 1,5 để bao gồm mối quan hệ "xảy ra trước", ít nhất một phần để kiểm tra khóa kép an toàn; từ những gì tôi hiểu, mối quan hệ "xảy ra trước" có nghĩa là ghi vào biến biến động khiến tất cả biến được lưu trong chuỗi được ghi vào bộ nhớ chính và sau khi đọc từ biến dễ bay hơi, tất cả biến được lưu trong bộ nhớ cache được coi là cũ và phải đọc lại từ bộ nhớ chính, để mọi thứ được viết trước khi ghi vào biến biến động được đảm bảo "xảy ra trước" sau đó được đọc từ biến đó.

Stack Overflow seems to believe rằng, đối với C#, volatile là không cần thiết cho khóa kiểm tra lại (mặc dù lưu ý lo ngại rằng điều này có thể được cụ thể cho CPU nhất định hoặc để thực hiện của Microsoft), đồng thời cũng tin rằng ngữ nghĩa của tuyên bố synchronized Java là exactly the same như câu lệnh lock của C#, cho thấy rằng cùng một vấn đề được xác định trong Java cũng sẽ tồn tại đối với C#, trừ khi một số khác biệt lớn khác tồn tại trong ngữ nghĩa của khóa được kiểm tra kép giữa hai ngôn ngữ.

Vậy ... điều gì là chính xác? Khóa kép trong C# có thực sự ít nguy hiểm hơn trong Java không? Nếu vậy, ngữ nghĩa ngôn ngữ khác nhau để làm cho trường hợp đó là gì?

Nếu không, điều gì đặc biệt có thể sai nếu không có volatile? Liệu ngữ nghĩa của volatile trong C# thiết lập một mối quan hệ "xảy ra-trước" như Java, để khóa kiểm tra kép là an toàn trong C# với volatile vì nó có trong Java từ 1.5 không?

+0

Xem [this] (http://blogs.msdn.com/b/ericlippert/archive/2011/06/16/atomicity-volatility-and-immutability-are-different-part-three.aspx) và [ này] (http://stackoverflow.com/a/5821201/116614). – mellamokb

Trả lời

2

Từ MSDN: "Từ khóa dễ bay hơi chỉ ra rằng một trường có thể được sửa đổi bởi nhiều chuỗi đang thực thi cùng lúc. Các trường được khai báo dễ bay hơi không phải tuân theo tối ưu hóa trình biên dịch giả định truy cập bằng một chuỗi duy nhất. giá trị cập nhật nhất hiện diện trong trường mọi lúc. "

Vì vậy, dễ bay hơi chỉ hữu ích nếu bạn thay đổi giá trị của biến từ nhiều chuỗi. Nếu bạn khóa() các vùng mã mà chia sẻ tài nguyên với cùng một đối tượng khóa, bạn được bảo đảm rằng chỉ có một luồng có thể truy cập vào các vùng mã đó cùng một lúc, thì không cần đến biến động trừ khi bạn sửa đổi đối tượng khóa (đó là một ý tưởng thực sự tồi) .

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