多线程程序中的Lock()

时间:2016-07-25 14:47:45

标签: c# multithreading locking

我有一个简单的程序来模拟我的错误情况。我有一个单例类,它从几个线程获取消息。必须阻止执行,直到执行该函数。

class Program
{
    private static TestClass test;
    static void Main(string[] args)
    {
        Thread a = new Thread(TestFunctionB);
        a.Start();

        Thread b = new Thread(TestFunctionB);
        b.Start();
    }

    private static void TestFunctionB()
    {
        TestClass test = TestClass.Instance;
        for (int i = 0; i < 15; i++)
        {
            test.Handle(i, Thread.CurrentThread.ManagedThreadId);
        }
    }
}

class TestClass
{
    private readonly object _lockObject;
    private static TestClass _instance;

    private TestClass()
    {
        _lockObject = new object();
    }

    public static TestClass Instance
    {
        get { return _instance ?? (_instance = new TestClass()); }
    }

    private void RunLocked(Action action)
    {
        lock (_lockObject)
        {
            action.Invoke();
        }
    }

    public void Handle(int counter, int threadId)
    {
        Console.WriteLine("\nThreadId = {0}, counter = {1}\n", threadId, counter);

        RunLocked(() =>
                  {
                      Console.WriteLine("\nFunction Handle ThreadId = {0}, counter = {1}\n", threadId, counter);

                      for (int i = 0; i < 30; i++)
                      {
                          Console.WriteLine("Funktion Handle threadId = {0}, counter = {1}, i = {2}", threadId, counter, i);
                          //Thread.Sleep(100);
                      }

                  });

        Console.WriteLine("\nFunction Handle free ThreadId = {0}, counter = {1}\n", threadId, counter);

    }


}

`

我怀疑线程一个接一个地写输出,但在控制台中线程输出是混合的。锁定声明不正确吗?

1 个答案:

答案 0 :(得分:1)

我不知道这是你唯一的问题,但class TestClass { private readonly object _lockObject; private readonly static Lazy<TestClass> _instance = new Lazy<TestClass>(x=> new TestClass()); private TestClass() { _lockObject = new object(); } public static TestClass Instance { get { return _instance.Value; } } ... } 不是原子问题,你最终可能会返回多个实例。

使用Lazy<T>类来保证只创建一个单例实例。

class TestClass
{
    private readonly object _lockObject;
    private static readonly object _singletonLock = new Object();
    private static TestClass _instance;

    private TestClass()
    {
        _lockObject = new object();
    }

    public static TestClass Instance
    {
        get 
        { 
            if(_instance == null)
            {
                lock(_singletonLock)
                {
                    if(_instance == null)
                    {
                        _instance = new TestClass ();
                    }
                }
            }
            return _instance; 
        }
    }
    ...
}

如果您无法访问.NET 4.0或更高版本,则需要锁定单例创建。

{{1}}