多线程C#singleton中的问题:变量未初始化

多线程C#singleton中的问题:变量未初始化,c#,multithreading,thread-safety,singleton,C#,Multithreading,Thread Safety,Singleton,这是一个简化版的生产代码,使用单线程运行在多线程中与传统的单例相比,另外一件事是我在锁定部分初始化了客户机。 当我试图通过以下方式获取客户端:client-client=Singleton.Instance.GetClient(),则客户端可能为空(但可能性非常小) 我就是这样测试它的: static void Main(string[] args) { Console.WriteLine("Input thread count: ");

这是一个简化版的生产代码,使用单线程运行在多线程中与传统的单例相比,另外一件事是我在
锁定部分初始化了客户机。

当我试图通过以下方式获取客户端:
client-client=Singleton.Instance.GetClient()
,则
客户端
可能为空(但可能性非常小

我就是这样测试它的:

    static void Main(string[] args)
    {
        Console.WriteLine("Input thread count: ");
        int threadCount = Int32.Parse(Console.ReadLine().Trim());
        List<Task> tasks = new List<Task>(threadCount);

        for (int i = 0; i < threadCount; ++i)
        {
            tasks.Add(Task.Factory.StartNew(() => DoStuff()));
        }

        Task.WaitAll(tasks.ToArray());
        Console.WriteLine("All threads complete");
    }

    private static void DoStuff()
    {
        Client client = Singleton.Instance.GetClient();
        if (client.Value != 10)
        {
            Console.WriteLine($"Thread: {Thread.CurrentThread.ManagedThreadId}.");
        }
    }

我不知道什么是不同的,什么是错误的,谢谢你的帮助

只要在锁内调用instance=new Singleton(),instance就不再为null,这意味着对Singleton的单独(线程化)调用。instance立即返回,对该实例的GetClient调用将是从第一次调用开始与InitClient的竞争条件


在构造函数内部初始化可确保“实例”本身在创建后立即初始化。因此,来自不同线程的后续调用不会与任何东西竞争。

只要在锁中调用instance=new Singleton(),instance就不再为null,这意味着对Singleton的单独(线程化)调用。instance立即返回,在该实例上对GetClient的调用将是第一次调用时与InitClient的竞争条件


在构造函数内部初始化可确保“实例”本身在创建后立即初始化。因此,来自不同线程的后续调用不会与任何东西竞争。

您应该将
实例设置为volatile。请查看该类。它只做了一件事,延迟初始化,并且做得很好。您应该使
实例
易失性。看看这个类。它只做一件事,延迟初始化,而且做得很好。
    static void Main(string[] args)
    {
        Console.WriteLine("Input thread count: ");
        int threadCount = Int32.Parse(Console.ReadLine().Trim());
        List<Task> tasks = new List<Task>(threadCount);

        for (int i = 0; i < threadCount; ++i)
        {
            tasks.Add(Task.Factory.StartNew(() => DoStuff()));
        }

        Task.WaitAll(tasks.ToArray());
        Console.WriteLine("All threads complete");
    }

    private static void DoStuff()
    {
        Client client = Singleton.Instance.GetClient();
        if (client.Value != 10)
        {
            Console.WriteLine($"Thread: {Thread.CurrentThread.ManagedThreadId}.");
        }
    }
private Singleton()
{
    this.InitClient();
}