单例模式的五种写法
程序员文章站
2022-07-13 23:37:46
...
- 常规写法(懒汉式),用在单线程,会有多线程问题
//常规写法
public sealed class Singleton1
{
private Singleton1()
{
Debug.Log("执行了 Singleton1 构造函数");
}
private static Singleton1 m_Instance;
public static Singleton1 Instance
{
get
{
if (m_Instance == null)
{
m_Instance = new Singleton1();
}
return m_Instance;
}
}
public void Excute()
{
Debug.Log("执行了 Singleton1");
}
}
- 加同步锁法,考虑多线程安全问题,不过该写法每次都加锁是比较耗时的操作,所以有了第三种写法
//加同部锁
public sealed class Singleton2
{
private Singleton2()
{
Debug.Log("执行了 Singleton2 构造函数");
}
private static Object SyncObj = new Object();
private static Singleton2 m_Instance;
public static Singleton2 Instance
{
get
{
lock (SyncObj)
{
if (m_Instance == null)
{
m_Instance = new Singleton2();
}
}
return m_Instance;
}
}
public void Excute()
{
Debug.Log("执行了 Singleton2");
}
}
- 加同步锁+前后判断,在加锁之前之后都判断一次实例是否已创建,如果已创建则直接得到该实例,不去加锁,不过该写法写起来比较复杂
public sealed class Singleton3
{
private Singleton3()
{
Debug.Log("执行了 Singleton3 构造函数");
}
private static Object SyncObj = new Object();
private static Singleton3 m_Instance;
public static Singleton3 Instance
{
get
{
if (m_Instance == null)
{
lock (SyncObj)
{
if (m_Instance == null)
{
m_Instance = new Singleton3();
}
}
}
return m_Instance;
}
}
public void Excute()
{
Debug.Log("执行了 Singlegon3");
}
}
- 利用静态构造函数法(饿汉式),利用静态构造函数只会执行一次的特性。有两种写法,不过区别不大
//利用静态构造函数
//第一种(更简便点)
public sealed class Singleton4
{
private Singleton4()
{
Debug.Log("执行了 Singleton4 构造函数");
}
private static Singleton4 m_Instance = new Singleton4();
public static Singleton4 Instance
{
get { return m_Instance; }
}
public void Excute()
{
Debug.Log("执行了 Singleton4");
}
}
//第二种
public sealed class Singleton4
{
private Singleton4()
{
}
private static Singleton4 m_Instance = null;
//静态构造函数
static Singleton4()
{
m_Instance = new Singleton4();
Debug.Log("执行了 Singleton4 静态构造函数");
}
public static Singleton4 Instance
{
get { return m_Instance; }
}
public void Excute()
{
Debug.Log("执行了 Singleton4");
}
}
- 利用嵌套内部类,初始化工作由内部类的一个静态成员来完成,这样就实现了延迟初始化,也是懒汉式写法
//利用嵌套内部类
public sealed class Singleton5
{
private Singleton5()
{
Debug.Log("执行了 Singleton5 构造函数");
}
public static Singleton5 Instance
{
get
{
return Temp.m_Singleton2;
}
}
public void Excute()
{
Debug.Log("执行了 Singleton5");
}
class Temp
{
private Temp()
{
}
internal static readonly Singleton5 m_Singleton2 = new Singleton5();
}
}
总结:推荐第4、5种写法