Đây là đóng góp của tôi cho sự hiểu biết chung về hành vi này ... Nó không nhiều, chỉ là một minh chứng (dựa trên bản demo của xkip) cho thấy hành vi của một câu dễ bay hơi một giá trị int không bay hơi (tức là "bình thường"), song song -bên cạnh, trong cùng một chương trình ... đó là những gì tôi đã tìm kiếm khi tôi tìm thấy chủ đề này.
using System;
using System.Threading;
namespace VolatileTest
{
class VolatileTest
{
private volatile int _volatileInt;
public void Run() {
new Thread(delegate() { Thread.Sleep(500); _volatileInt = 1; }).Start();
while ( _volatileInt != 1 )
; // Do nothing
Console.WriteLine("_volatileInt="+_volatileInt);
}
}
class NormalTest
{
private int _normalInt;
public void Run() {
new Thread(delegate() { Thread.Sleep(500); _normalInt = 1; }).Start();
// NOTE: Program hangs here in Release mode only (not Debug mode).
// See: http://stackoverflow.com/questions/133270/illustrating-usage-of-the-volatile-keyword-in-c-sharp
// for an explanation of why. The short answer is because the
// compiler optimisation caches _normalInt on a register, so
// it never re-reads the value of the _normalInt variable, so
// it never sees the modified value. Ergo: while ( true )!!!!
while ( _normalInt != 1 )
; // Do nothing
Console.WriteLine("_normalInt="+_normalInt);
}
}
class Program
{
static void Main() {
#if DEBUG
Console.WriteLine("You must run this program in Release mode to reproduce the problem!");
#endif
new VolatileTest().Run();
Console.WriteLine("This program will now hang!");
new NormalTest().Run();
}
}
}
Có một số giải thích ngắn gọn thực sự xuất sắc ở trên, cũng như một số tài liệu tham khảo tuyệt vời. Cảm ơn tất cả vì đã giúp tôi quay đầu lại volatile
(ít nhất là đủ để biết không dựa vào volatile
bản năng đầu tiên của tôi ở đâulock
).
Chúc mừng, và Cảm ơn vì TẤT CẢ những con cá. Keith.
Tái bút: Tôi rất quan tâm đến bản demo của yêu cầu ban đầu, đó là: "Tôi muốn thấy một int biến động tĩnh hoạt động chính xác khi một int tĩnh hoạt động sai.
Tôi đã thử và thất bại trong thử thách này. (Thực ra tôi đã bỏ cuộc khá nhanh ;-). Trong mọi thứ tôi đã thử với các vars tĩnh, chúng hoạt động "chính xác" bất kể chúng có dễ bay hơi hay không ... và tôi muốn giải thích TẠI SAO lại như vậy, nếu thực sự là như vậy ... trình biên dịch không lưu trữ các giá trị của các vars tĩnh trong các thanh ghi (tức là nó lưu vào bộ đệm một tham chiếu đến địa chỉ heap đó)?
Không, đây không phải là một câu hỏi mới ... đó là một nỗ lực để khiến cộng đồng quay trở lại câu hỏi ban đầu.