Từ khóa volatile
trong C# là tất cả về đọc/viết sắp xếp lại, do đó, nó là một cái gì đó khá bí truyền.
http://www.albahari.com/threading/part4.aspx#_Memory_Barriers_and_Volatility
(mà tôi cho là một trong những "kinh bổn" về luồng) viết:
Các từ khóa dễ bay hơi chỉ thị các trình biên dịch để tạo ra một Acquire hàng rào trên tất cả các đọc từ trường , và một hàng rào phát hành trên mỗi viết cho lĩnh vực đó.Một rào cản ngăn cản các lần đọc/ghi khác bị di chuyển trước hàng rào; một hàng rào phát hành ngăn cản các lần đọc/ghi khác bị di chuyển sau hàng rào. Những “nửa hàng rào” này nhanh hơn hàng rào đầy đủ bởi vì chúng cung cấp cho phạm vi thời gian chạy và phần cứng hơn để tối ưu hóa.
Nó là một cái gì đó khá đọc :-)
Bây giờ ... Những gì nó không có nghĩa là:
- Nó không có nghĩa là một giá trị sẽ được đọc tại/sẽ được ghi tại
nó chỉ đơn giản có nghĩa là nếu bạn đọc một cái gì đó từ một biến không ổn định, tất cả mọi thứ el se đã được đọc/ghi trước khi đọc "đặc biệt" này sẽ không được di chuyển sau khi đọc "đặc biệt" này. Vì vậy, nó tạo ra một rào cản. Vì vậy, nghịch lý, bằng cách đọc từ một biến dễ bay hơi, bạn đảm bảo rằng tất cả các ghi bạn đã làm cho bất kỳ biến khác (dễ bay hơi hay không) tại thời điểm đọc sẽ được thực hiện.
Ghi dễ bay hơi có thể quan trọng hơn, và là thứ được bảo đảm một phần bởi CPU Intel và thứ gì đó không được đảm bảo bởi phiên bản Java đầu tiên: không viết lại sắp xếp lại. Vấn đề là:
object myrefthatissharedwithotherthreads = new MyClass(5);
nơi
class MyClass
{
public int Value;
MyClass(int value)
{
Value = value;
}
}
Bây giờ ... biểu hiện có thể được tưởng tượng là:
var temp = new MyClass();
temp.Value = 5;
myrefthatissharedwithotherthreads = temp;
nơi temp
được một cái gì đó được tạo ra bởi trình biên dịch mà bạn có thể' t thấy.
Nếu ghi có thể được sắp xếp lại, bạn có thể có:
var temp = new MyClass();
myrefthatissharedwithotherthreads = temp;
temp.Value = 5;
và thread khác có thể nhìn thấy một phần khởi MyClass
, bởi vì giá trị của myrefthatissharedwithotherthreads
có thể đọc trước lớp MyClass
đã hoàn tất khởi tạo.
'volatile' ngăn hướng dẫn sắp xếp lại xung quanh quyền truy cập biến. Nó khá phức tạp. Xem http://www.albahari.com/threading/part4.aspx#_Memory_Barriers_and_Volatility – xanatos
[Câu trả lời của Eric Lippert cho một câu hỏi khác] (http://stackoverflow.com/a/26315297/517852) thực sự có mô tả rất tốt về sự khác biệt trong ngữ nghĩa của biến động giữa C++ và C#. –