概念
volatile 关键字指示一个字段可以由多个同时执行的线程修改。
出于性能原因,编译器,运行时系统甚至硬件都可能重新排列对存储器位置的读取和写入。
声明为 volatile 的字段将从某些类型的优化中排除。
样例
public class Worker
{
// This method is called when the thread is started.
public void DoWork()
{
bool work = false;
while (!_shouldStop)
{
work = !work; // simulate some work
}
Console.WriteLine("Worker thread: terminating gracefully.");
}
public void RequestStop()
{
_shouldStop = true;
}
// Keyword volatile is used as a hint to the compiler that this data
// member is accessed by multiple threads.
private volatile bool _shouldStop;
}
public class WorkerThreadExample
{
public static void Main()
{
// Create the worker thread object. This does not start the thread.
Worker workerObject = new Worker();
Thread workerThread = new Thread(workerObject.DoWork);
// Start the worker thread.
workerThread.Start();
Console.WriteLine("Main thread: starting worker thread...");
// Loop until the worker thread activates.
while (!workerThread.IsAlive)
;
// Put the main thread to sleep for 500 milliseconds to
// allow the worker thread to do some work.
Thread.Sleep(500);
// Request that the worker thread stop itself.
workerObject.RequestStop();
// Use the Thread.Join method to block the current thread
// until the object's thread terminates.
workerThread.Join();
Console.WriteLine("Main thread: worker thread has terminated.");
}
// Sample output:
// Main thread: starting worker thread...
// Worker thread: terminating gracefully.
// Main thread: worker thread has terminated.
}
将 volatile 修饰符添加到 _shouldStop 的声明后,将始终获得相同的结果。
但是,如果 _shouldStop 成员上没有该修饰符,则行为是不可预测的。 DoWork 方法可能会优化成员访问,从而导致读取陈旧数据。
鉴于多线程编程的性质,读取陈旧数据的次数是不可预测的。 不同的程序运行会产生一些不同的结果。
Volatile 类
- 在多处理器系统上,Volatile Write操作确保写入存储器位置的值立即对所有处理器可见。 Volatile Read操作获得由任何处理器写入存储器位置的最新值。 这些操作可能需要刷新处理器缓存,这可能会影响性能。
- 在单处理器系统上,Volatile 读取和写入确保将值读取或写入存储器并且不缓存(例如,在处理器寄存器中)。 因此,您可以使用这些操作来同步对可以由另一个线程或硬件更新的字段的访问。