简体   繁体   English

多线程程序中的Lock()

[英]Lock() in multithreading program

I have a simple program that simulates my error situation. 我有一个模拟我的错误情况的简单程序。 I have a singleton class that gets a messages from several threads. 我有一个单例类,它从多个线程获取消息。 The execution must be blocked until the function is executed. 在执行该功能之前,必须阻止执行。

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);

    }


}

` `

I excpect that threads write the output one after another, but in the console the threads outputs are mixed. 我认为线程会一个接一个地写输出,但是在控制台中线程输出是混合的。 Is the lock statement not correct? 锁语句不正确吗?

I don't know if it is your only problem but get { return _instance ?? (_instance = new TestClass()); } 我不知道这是否是您唯一的问题,但get { return _instance ?? (_instance = new TestClass()); } get { return _instance ?? (_instance = new TestClass()); } get { return _instance ?? (_instance = new TestClass()); } is not atomic, you may end up with more than one instance returned. get { return _instance ?? (_instance = new TestClass()); }不是原子的,最终可能会返回多个实例。

Use the Lazy<T> class to guarantee that only one instance of the singleton is created. 使用Lazy<T>类可确保仅创建一个单例实例。

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; }
    }
    ...
}

If you don't have access to .NET 4.0 or newer you will need to lock around your singleton creation. 如果您无权访问.NET 4.0或更高版本,则需要锁定单例创建。

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; 
        }
    }
    ...
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM