Below is a C# code example which is a verbatim translation of a broken Java code (which has proven to break (i. e. the 2nd thread may fail to observe the change of sha
This should get stuck in an infinite loop (I can't test it right now)
public class Test
{
private bool loop = true;
public static void Main()
{
Test test = new Test();
Thread thread = new Thread(DoStuff);
thread.Start(test);
Thread.Sleep(1000);
test.loop = false;
Console.WriteLine("loop is now false");
}
private static void DoStuff(object o) {
Test test = (Test)o;
Console.WriteLine("Entering loop");
while (test.loop) {
}
Console.WriteLine("Exited loop");
}
}
Try running the RELEASE build of the following program (do NOT run it from the debugger otherwise the demonstration won't work - so run the release build via "Debug | Start without debugging"):
using System;
using System.Threading;
using System.Threading.Tasks;
namespace Demo
{
internal class Program
{
private void run()
{
Task.Factory.StartNew(resetFlagAfter1s);
int x = 0;
while (flag)
++x;
Console.WriteLine("Done");
}
private void resetFlagAfter1s()
{
Thread.Sleep(1000);
flag = false;
}
private volatile bool flag = true;
private static void Main()
{
new Program().run();
}
}
}
The program will terminate after a second.
Now remove the volatile
from the line
private volatile bool flag = true; // <--- Remove volatile from this
After doing so, the program will now never terminate. (Tested on Windows 8 x64, .Net 4.5)
Please note, however, that in some cases it is more appropriate to use Thread.MemoryBarrier()
rather than declaring the variable volatile
, i.e.:
while (flag)
{
Thread.MemoryBarrier();
++x;
}
For more information, see http://blogs.msdn.com/b/brada/archive/2004/05/12/130935.aspx