我对代码中的几个段有疑问,设置或获取静态元素的值(使用锁)。
那么,这段代码是否正确?如果我在某一刻调用MethodB和MethodC会发生什么?实际上,它们都在一个时刻(来自不同的lock()段)调用一个静态方法,是否安全?
public class ThreadsClass
{
public static class StaticHelper
{
public static string NameStatic { get; set; }
public static void MethodCountStatic(int num)
{
for (int i = 0; i <= num; i++)
{
Console.WriteLine("{0} step...",i);
}
}
}
private Object lockObject = new Object();
public void MethodA()
{
lock (lockObject)
{
StaticHelper.NameStatic = "somename";
}
}
public void MethodB()
{
lock (lockObject)
{
StaticHelper.MethodCountStatic(1000000);
}
}
public void MethodC()
{
lock (lockObject)
{
StaticHelper.MethodCountStatic(500000000);
}
}
}
答案 0 :(得分:2)
嗯,是的,没有。
在代码的当前状态中,它是线程安全的,因为MethodCountStatic
不保留任何状态,并且没有任何内容读取NameStatic
。我认为并非总是如此。
如果继续构建代码,至少会出现两个问题;
StaticHelper
是公开的,因此任何类都可以调用任何方法或访问其中的任何属性而无需锁定。
如果你创建两个ThreadsClass
实例,它们有两个不同的锁,这样就不会阻止它们调用或访问StaticClass中的属性而不会看到彼此的锁。
如果您希望类线程安全,则需要使StaticHelper
private和lockObject
static来克服这两个问题。
编辑:如果你想让StaticHelper公开并保持状态,你可能最好不要在类本身内移动锁,a'la;
public static class StaticHelper
{
private static Object lockObject = new Object();
private static string _nameStatic;
public static string NameStatic {
get { lock (lockObject) return _nameStatic; }
set { lock (lockObject) _nameStatic = value; }
}
public static void MethodCountStatic(int num) {
lock (lockObject) {
// Your method here...
}
}
}
这样,锁定就被隔离到需要它的类而不是遍布很多不相关的类。
答案 1 :(得分:0)
是的,在当前情况下,方法MethodB
和MethodC
的功能是线程安全的。但是有可能访问静态类的公共成员忽略这些方法,请注意。