Jer*_*acs 0 c# singleton thread-safety
我可以安全地IsBusy从多个线程读取实例化单例的布尔属性,而不会导致任何线程安全问题,或者我已经处于危险水域?
除非你有任何记忆障碍,否则如果价值可能发生变化,你可能处于危险的水域.
让我们把这个中的单例部分排除在等式之外,因为它不是特别相关.考虑这个简单的例子:
// Not safe!
public class BusyIndicator
{
public bool IsBusy { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
现在,如果你有一个线程:
foo.IsBusy = true;
// do some work
foo.IsBusy = false;
Run Code Online (Sandbox Code Playgroud)
和另一个线程,仅在IsBusy设置为true 后启动,具有:
// Do some work
while (foo.IsBusy) { }
Run Code Online (Sandbox Code Playgroud)
...那么第二个线程可能永远旋转......没有内存屏障来确保它"看到"第一个线程的变化.
您可以使用锁定或使用安全地实现此目的Interlocked,例如
// 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); }
}
}
Run Code Online (Sandbox Code Playgroud)