"For non-volatile fields, optimization techniques that reorder instructions can lead to unexpected and unpredictable results in multi-threaded programs that access fields without synchronization such as that provided by the lock-statement."
What does it mean? In a multi-CPU and multi-threaded environment, a value could be temporarily stored in registers and multiple levels of cache, and the value change by a thread in one CPU may not be seen immediately by another thread run in another CPU. This could lead to some unpredictable issues.
We can guarantee to get a refresh value by declaring a volatile field:
using System;In above code snippet, Thread1 will immediately see the latest "finished" value updated by a Thread2, and guarantee to finish and break the infinite loop. Without volatile declared, Thread1 could (not always) never be ended in some systems.
using System.Threading;
class Test
{
public static bool finished = false;
private static object syncLock = new object();
static void Main()
{
new Thread(new ThreadStart(Thread1)).Start();
new Thread(new ThreadStart(Thread2)).Start();
Console.Read();
}
static void Thread1()
{
while (true)
{
if (finished)
{
Console.WriteLine("Finished.");
break;
}
}
}
static void Thread2()
{
lock (syncLock)
{
finished = true;
}
}
}
One important note is that volatile field doesn't mean it's thread-safe. Locking mechanism is still required in some scenarios. With a locked field, the value of that field is guarantee to be the latest one, and volatile is unnecessary in such case.
(Updated 2006/9):
My original understanding may not be correct. Some people argue that volatile only means the sequence of accessing a volatile member won't reordered, it doesn't mean that a value assignment will be immediately visible to all processors. However I could not verify this without a real environment.