多线程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();
}