当前线程中的单例 [英] Singleton in current thread

查看:59
本文介绍了当前线程中的单例的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的单身人士如下:

 公共类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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆