【说明】
- 构造函数为私有函数(private),禁止他人创建实例
- 实例为静态(static),属于类,在需要时创建该实例
- syncObj 定义了一个同步锁,用来锁住线程
【1 - 单线程】- C++
- 构造函数为私有函数(private),禁止他人创建实例
- 实例为静态(static),在需要时创建该实例
public sealed class Singleton1
{
private Singleton1()
{
}
private static Singleton1 instance = null;
public static Singleton1 Instance
{
get
{
if (instance == null)
instance = new Singleton1();
return instance;
}
}
}
【2 - 多线程,效率低】- C++
- 过程:第一个线程上锁,创建实例,第二个线程等待,然后,第二个线程上锁,已存在实例,不重复创建实例
- 效率低,每次通过Instance得到Singleton2实例的时候,都会加上同步锁,但是加锁是很耗时的操作
public sealed class Singleton2
{
private Singleton2()
{
}
private static readonly object syncObj = new object();
private static Singleton2 instance = null;
public static Singleton2 Instance
{
get
{
lock (syncObj)
{
if (instance == null)
instance = new Singleton2();
}
return instance;
}
}
}
【3 - 多线程,效率高】- C++
- 效率高,在上锁之前先判断是否存在实例,若不存在才上锁
public sealed class Singleton3
{
private Singleton3()
{
}
private static object syncObj = new object();
private static Singleton3 instance = null;
public static Singleton3 Instance
{
get
{
if (instance == null)
{
lock (syncObj)
{
if (instance == null)
instance = new Singleton3();
}
}
return instance;
}
}
}
【4 - 静态构造函数】- C#
- C#的静态构造函数能保证只调用一次,即C#在调用静态构造函数时初始化静态变量
- 调用的时机不由程序员掌控,而是当 .NET运行时发现第一次使用一个类时自动调用该类的静态构造函数
- 会过早的创建实例,降低内存的使用效率
public sealed class Singleton4
{
private Singleton4()
{
Console.WriteLine("An instance of Singleton4 is created.");
}
public static void Print()
{
Console.WriteLine("Singleton4 Print");
}
private static Singleton4 instance = new Singleton4();
public static Singleton4 Instance
{
get
{
return instance;
}
}
}
【5 - 静态构造函数】- C#
- C#的方法和属性在默认情况下均为 private 私有
- Nested 是定义的私有类,当第一次用到这个嵌套类型时,会调用静态构造函数创建 Singleton5 的实例 instance
- Nested 只在方法Singleton5.Instance 中被用到,又为私有即他人无法调用
- 当第一次通过Singleton5.Instance得到 Singleton5 的实例时,会自动调用 Nested 的静态构造函数创建实例 instance;不调用 Singleton5.Instance 时就不会触发 .NET 运行时调用 Nested,也不会创建实例
public sealed class Singleton5
{
Singleton5()
{
Console.WriteLine("An instance of Singleton5 is created.");
}
public static void Print()
{
Console.WriteLine("Singleton5 Print");
}
public static Singleton5 Instance
{
get
{
return Nested.instance;
}
}
class Nested
{
static Nested()
{
}
internal static readonly Singleton5 instance = new Singleton5();
}
}