当前线程中的单例 [英] Singleton in current thread
问题描述
我的单身人士如下:
公共类CurrentSingleton
{
private static CurrentSingleton uniqueInstance = null;
私有静态对象syncRoot = new Object();
private CurrentSingleton(){}
public static CurrentSingleton getInstance()
{
if(uniqueInstance == null)
{
锁定(syncRoot)
{
if(uniqueInstance == null)
uniqueInstance = new CurrentSingleton();
}
}
返回uniqueInstance;
}
}
我想检查一下,如果我有两个线程,有两个不同的单例吗?我想,我将有两个不同的单例(具有不同的引用),所以我在做什么:
class Program
{
static void Main(string [] args)
{
int currentCounter = 0;
for(int i = 0; i< 100; i ++)
{
cs1 = null;
cs2 = null;
线程ct1 =新线程(cfun1);
线程ct2 =新线程(cfun2);
ct1.Start();
ct2.Start();
if(cs1 == cs2)currentCounter ++;
}
Console.WriteLine(currentCounter);
Console.Read();
}
静态CurrentSingleton CS1;
静态CurrentSingleton cs2;
静态无效cfun1()
{
cs1 = CurrentSingleton.getInstance();
}
静态无效cfun2()
{
cs2 = CurrentSingleton.getInstance();
}
}
我想我应该得到 currentCounter = 0
(在这种情况下,每两个单例都是不同的-因为它们是由其他威胁者创建的)。不幸的是,例如,我得到了 currentCounter = 70
,因此在70种情况下,我具有相同的单身汉...您能告诉我为什么吗?
我想检查一下,如果我有两个线程,是否有两个不同的单例
不,没有。在每个 AppDomain
而不是每个线程中共享一个静态
字段。
如果您希望每个线程具有单独的值,建议使用 ThreadLocal< T>
来存储支持数据,因为这将为每个线程数据提供一个很好的包装器。 / p>
另外,在C#中,通常最好通过 Lazy< T>
而不是通过双重检查来实现惰性单例锁定。看起来像这样:
公共密封类CurrentSingleton //密封单例(如果可能)
{
private静态Lazy< CurrentSingleton> uniqueInstance =新的Lazy< CurrentSingleton>(()=> new CurrentSingleton());
private CurrentSingleton(){}
公共静态CurrentSingleton实例//使用属性,因为这是C#...
{
get {return uniqueInstance.Value ; }
}
}
要创建一个为每个线程提供一个实例的类,您可以使用:
公共密封类InstancePerThread
{
private static ThreadLocal< InstancePerThread>实例=新ThreadLocal< InstancePerThread>((()=>新InstancePerThread());
私有InstancePerThread(){}
公共静态InstancePerThread实例
{
get {返回instance.Value; }
}
}
I have my singleton as below:
public class CurrentSingleton
{
private static CurrentSingleton uniqueInstance = null;
private static object syncRoot = new Object();
private CurrentSingleton() { }
public static CurrentSingleton getInstance()
{
if (uniqueInstance == null)
{
lock (syncRoot)
{
if (uniqueInstance == null)
uniqueInstance = new CurrentSingleton();
}
}
return uniqueInstance;
}
}
I would like check, if I will have two thread, are there two different singletons? I think, I shall have two different singletons (with different references), so what I'm doing:
class Program
{
static void Main(string[] args)
{
int currentCounter = 0;
for (int i = 0; i < 100; i++)
{
cs1 = null;
cs2 = null;
Thread ct1 = new Thread(cfun1);
Thread ct2 = new Thread(cfun2);
ct1.Start();
ct2.Start();
if (cs1 == cs2) currentCounter++;
}
Console.WriteLine(currentCounter);
Console.Read();
}
static CurrentSingleton cs1;
static CurrentSingleton cs2;
static void cfun1()
{
cs1 = CurrentSingleton.getInstance();
}
static void cfun2()
{
cs2 = CurrentSingleton.getInstance();
}
}
I suppose that I should got currentCounter = 0
(in this case every two singleton are different - because are creating by other threrad). Unfortunately, I got for example currentCounter = 70
so in 70 cases I have the same singletons... Could you tell me why?
I would like check, if I will have two thread, are there two different singletons
No, there are not. A static
field is shared across each entire AppDomain
, not each thread.
If you want to have separate values per thread, I'd recommend using ThreadLocal<T>
to store the backing data, as this will provide a nice wrapper for per-thread data.
Also, in C#, it's typically better to implement a lazy singleton via Lazy<T>
instead of via double checked locking. This would look like:
public sealed class CurrentSingleton // Seal your singletons if possible
{
private static Lazy<CurrentSingleton> uniqueInstance = new Lazy<CurrentSingleton>(() => new CurrentSingleton());
private CurrentSingleton() { }
public static CurrentSingleton Instance // use a property, since this is C#...
{
get { return uniqueInstance.Value; }
}
}
To make a class that provides one instance per thread, you could use:
public sealed class InstancePerThread
{
private static ThreadLocal<InstancePerThread> instances = new ThreadLocal<InstancePerThread>(() => new InstancePerThread());
private InstancePerThread() {}
public static InstancePerThread Instance
{
get { return instances.Value; }
}
}
这篇关于当前线程中的单例的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!