线程安全c#

时间:2014-06-14 17:47:38

标签: c# multithreading locking

我对代码中的几个段有疑问,设置或获取静态元素的值(使用锁)。

那么,这段代码是否正确?如果我在某一刻调用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);
        }
    }
}

2 个答案:

答案 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)

是的,在当前情况下,方法MethodBMethodC的功能是线程安全的。但是有可能访问静态类的公共成员忽略这些方法,请注意。