Yes. You should make the code safe for multithreaded operations. The reason is because it is standard practice to make all static members thread-safe whether you expect the code to be run in multithreaded environment or not. Your current code has a staleness problem. That is one thread may call Reset
, but other threads calling Data
may never see the change. This can be fixed easily by marking MyData
as volatile
.
Update:
The issue of staleness that I am talking about is related to how the C# and JIT compilers optimize code. For example, consider two threads TA and TB. TA calls MyClass.Data
and thus reads the MyData
reference while TB changes the MyData
reference by calling Reset
. The compiler is free to reorder the reads and writes of MyData
by lifting them outside of loops, caching them in a CPU register, etc. What this means is that TA might miss a change in MyData
if it caches the reference in a CPU register or if TB does not commit its write to main memory immediately.
This is not just some theoretical problem that rarely occurs in practice. In fact, it is quite easy to demonstrate with the following program. Make sure you compile the code in the Release configuration and run it without the debugger (both are mandatory to reproduce the problem). A cursory glance suggests that this program should terminate in about 1 second, but alas it does not because m_Stop
is being cached by the worker thread and never sees that the main thread changed its value to true
. The simple fix is mark m_Stop
as volatile
. You can see my explanation here for information about the concept of memory barriers and the reordering of instructions.
public class Program
{
private static bool m_Stop = false;
public static void Main(string[] args)
{
var thread = new Thread(
() =>
{
int i = 0;
Console.WriteLine("begin");
while (!m_Stop)
{
i++;
}
Console.WriteLine("end");
});
thread.Start();
Thread.Sleep(1000);
m_Stop = true;
Console.WriteLine("exit");
}
}