Can I safely read a IsBusy
boolean property for an instantiated singleton from multiple threads without causing any thread-safety issues, or am I already in dangerous waters?
Unless you have any memory barriers, you're potentially in dangerous waters, if the value can ever change.
Let's take the singleton part of this out of the equation, as it's not particularly relevant. Consider this simple example:
// Not safe!
public class BusyIndicator
{
public bool IsBusy { get; set; }
}
Now if you have one thread which is along the lines of:
foo.IsBusy = true;
// do some work
foo.IsBusy = false;
and another thread, only started after IsBusy
is set to true, that has:
// Do some work
while (foo.IsBusy) { }
... then it's possible that the second thread will spin forever... there's no memory barrier to ensure that it "sees" the change from the first thread.
You can implement this safely either using locking or using Interlocked
, e.g.
// Safe (in terms of memory barriers)
public class BusyIndicator
{
private int busy = 0;
public bool IsBusy
{
get { return Interlocked.CompareExchange(ref busy, 0, 0) == 1; }
set { Interlocked.Exchange(ref busy, value ? 1 : 0); }
}
}
See more on this question at Stackoverflow