ThreadStatic 的 C# 单例模式设计
C# Singleton Pattern Designs for ThreadStatic
我想了解单例模式设计。我想从我的单例 class 为每个线程创建单独的实例。所以我在下面提供了两个设计。
正在运行
class Program
{
static void Main(string[] args)
{
Task.Factory.StartNew(() => Console.WriteLine(SingletonClass.Instance.GetHashCode()));
Task.Factory.StartNew(() => Console.WriteLine(SingletonClass.Instance.GetHashCode()));
Console.ReadLine();
}
}
public sealed class SingletonClass
{
[ThreadStatic]
private static SingletonClass _instance;
public static SingletonClass Instance
{
get
{
if (_instance == null)
{
_instance = new SingletonClass();
}
return _instance;
}
}
private SingletonClass()
{
}
}
它不起作用(抛出 NullReferenceException 且未创建实例。)
class Program
{
static void Main(string[] args)
{
Task.Factory.StartNew(() => Console.WriteLine(SingletonClass.Instance.GetHashCode()));
Task.Factory.StartNew(() => Console.WriteLine(SingletonClass.Instance.GetHashCode()));
Console.ReadLine();
}
}
public sealed class SingletonClass
{
[ThreadStatic]
private static SingletonClass _instance = new SingletonClass();
public static SingletonClass Instance
{
get
{
return _instance;
}
}
private SingletonClass()
{
}
}
我真的很奇怪为什么没有为第二个设计创建一个实例。有人可以解释一下吗?
而不是使用 [ThreadStatic]
然后你可以使用 ThreadLocal<T>
这将基本上实现你正在尝试的 [ThreadStatic]
.
public sealed class SingletonClass
{
private static ThreadLocal<SingletonClass> _instance;
static SingletonClass()
{
_instance = new ThreadLocal<SingletonClass>(() => new SingletonClass());
}
public static SingletonClass Instance
{
get
{
return _instance.Value;
}
}
private SingletonClass()
{
}
}
有关详细信息,请参阅:https://msdn.microsoft.com/en-us/library/dd642243(v=vs.110).aspx。
编辑:回答您的问题。
在 C# 中做的时候:
private static SingletonClass _instance = new SingletonClass();
不管它是否标有[ThreadStatic]
,它只会创建一个设置SingletonClass
.
实例的静态构造函数
C# 无法为每个线程创建静态构造函数。
这就是您可以使用 ThreadLocal<T>
的目的。如果我们以您的代码为例,那么 SingletonClass
的默认构造函数实际上变成了 "thread-static"
构造函数。
您问题的答案主要与 class 字段的初始化方式有关。
在第二个示例中,_instance
字段在声明时被初始化。每次在声明时初始化静态字段时,都会创建一个静态构造函数(如果您尚未声明它)。在编译时,初始化将移至静态构造函数中。这意味着你最终会得到这样的东西(没有复制 IL 代码,因为它更难理解):
public sealed class SingletonClass
{
[ThreadStatic]
private static SingletonClass _instance;
public static SingletonClass Instance
{
get
{
return _instance;
}
}
static SingletonClass()
{
_instance = new SingletonClass();
}
}
CLR 确保静态构造函数只被调用一次,无论您有多少个线程。查看上面的代码,这意味着对于您创建的两个任务,_instance
字段将只初始化一次(因为只会调用一次静态构造函数)。
我想了解单例模式设计。我想从我的单例 class 为每个线程创建单独的实例。所以我在下面提供了两个设计。
正在运行
class Program
{
static void Main(string[] args)
{
Task.Factory.StartNew(() => Console.WriteLine(SingletonClass.Instance.GetHashCode()));
Task.Factory.StartNew(() => Console.WriteLine(SingletonClass.Instance.GetHashCode()));
Console.ReadLine();
}
}
public sealed class SingletonClass
{
[ThreadStatic]
private static SingletonClass _instance;
public static SingletonClass Instance
{
get
{
if (_instance == null)
{
_instance = new SingletonClass();
}
return _instance;
}
}
private SingletonClass()
{
}
}
它不起作用(抛出 NullReferenceException 且未创建实例。)
class Program
{
static void Main(string[] args)
{
Task.Factory.StartNew(() => Console.WriteLine(SingletonClass.Instance.GetHashCode()));
Task.Factory.StartNew(() => Console.WriteLine(SingletonClass.Instance.GetHashCode()));
Console.ReadLine();
}
}
public sealed class SingletonClass
{
[ThreadStatic]
private static SingletonClass _instance = new SingletonClass();
public static SingletonClass Instance
{
get
{
return _instance;
}
}
private SingletonClass()
{
}
}
我真的很奇怪为什么没有为第二个设计创建一个实例。有人可以解释一下吗?
而不是使用 [ThreadStatic]
然后你可以使用 ThreadLocal<T>
这将基本上实现你正在尝试的 [ThreadStatic]
.
public sealed class SingletonClass
{
private static ThreadLocal<SingletonClass> _instance;
static SingletonClass()
{
_instance = new ThreadLocal<SingletonClass>(() => new SingletonClass());
}
public static SingletonClass Instance
{
get
{
return _instance.Value;
}
}
private SingletonClass()
{
}
}
有关详细信息,请参阅:https://msdn.microsoft.com/en-us/library/dd642243(v=vs.110).aspx。
编辑:回答您的问题。
在 C# 中做的时候:
private static SingletonClass _instance = new SingletonClass();
不管它是否标有[ThreadStatic]
,它只会创建一个设置SingletonClass
.
C# 无法为每个线程创建静态构造函数。
这就是您可以使用 ThreadLocal<T>
的目的。如果我们以您的代码为例,那么 SingletonClass
的默认构造函数实际上变成了 "thread-static"
构造函数。
您问题的答案主要与 class 字段的初始化方式有关。
在第二个示例中,_instance
字段在声明时被初始化。每次在声明时初始化静态字段时,都会创建一个静态构造函数(如果您尚未声明它)。在编译时,初始化将移至静态构造函数中。这意味着你最终会得到这样的东西(没有复制 IL 代码,因为它更难理解):
public sealed class SingletonClass
{
[ThreadStatic]
private static SingletonClass _instance;
public static SingletonClass Instance
{
get
{
return _instance;
}
}
static SingletonClass()
{
_instance = new SingletonClass();
}
}
CLR 确保静态构造函数只被调用一次,无论您有多少个线程。查看上面的代码,这意味着对于您创建的两个任务,_instance
字段将只初始化一次(因为只会调用一次静态构造函数)。