Sto*_*orm 11 c# static thread-safety
好吧,它比问题复杂一点.
class A
{
static int needsToBeThreadSafe = 0;
public static void M1()
{
needsToBeThreadSafe = RandomNumber();
}
public static void M2()
{
print(needsToBeThreadSafe);
}
}
Run Code Online (Sandbox Code Playgroud)
现在我要求在M1()和M2()之间调用'needsToBeThreadSafe'保持线程安全.
小智 21
怎么样:
public static void M1()
{
Interlocked.Exchange( ref needsToBeThreadSafe, RandomNumber() );
}
public static void M2()
{
print( Interlocked.Read( ref needsToBeThreadSafe ) );
}
Run Code Online (Sandbox Code Playgroud)
par*_*cle 19
您可能要问的是[ ThreadStatic ]属性.如果您希望每个使用该类的线程A都有自己独立的值,needsToBeThreadSafe那么您只需要使用[ ThreadStatic ]属性来装饰该字段.
有关详细信息,请参阅MSDN文档ThreadStaticAttribute.
您有两种选择:给出您提供的代码最简单的是volatile关键字.声明needsToBeThreadSafe为static volatile int,这将保证引用该变量的任何线程都将获得"最新"副本,并且该变量不会缓存在您的代码中.
话虽这么说,如果你想更一般地确保M1()和M2()"原子地"(或至少完全相互)执行,那么你想要使用lock.最干净的语法是使用"锁定块",如下所示:
private static object locker = new Object();
//..
public static void M1()
{
lock(locker)
{
//..method body here
}
}
public static void M2()
{
lock(locker)
{
//..method body here
}
}
Run Code Online (Sandbox Code Playgroud)
至于采取哪种方法,这取决于你,应该由代码决定.如果你只需要确保成员赋值传播到所有线程并且没有缓存,那么volatile关键字就更简单了,并且可以很好地完成工作.如果超出这个范围,你可能想要去lock.