设计模式创建型之单例模式
单例就是在应用程序中保证类型只有一个实例。
创建一个简单的单例,代码如下
public class Singleton { private Singleton() //构造私有化,防止外部New { } private static Singleton _singleton = null; //对外提供一个获取实例的方法 public static Singleton CreateInstance() { if (_singleton == null) { _singleton= new Singleton(); } return _singleton; } }
这样存在的问题是多线程时,线程不安全,升级如下
public class Singleton { private Singleton() //构造私有化,防止外部New { } private static Singleton _singleton = null; private static object _lockObject = new object(); //对外提供一个获取实例的方法 public static Singleton CreateInstance() { lock (_lockObject)//确保任意时刻只有一个线程访问 { if (_singleton == null) { _singleton = new Singleton(); } } return _singleton; } }
线程 安全,但是有性能问题,继续升级如下
public class Singleton { private Singleton() //构造私有化,防止外部New { } private static Singleton _singleton = null; private static object _lockObject = new object(); //对外提供一个获取实例的方法 public static Singleton CreateInstance() { if (_singleton == null) //对像不为空时直接返回,不用排队取锁,提高性能 { lock (_lockObject)//确保任意时刻只有一个线程访问 { if (_singleton == null) { _singleton = new Singleton(); } } } return _singleton; } }
这样 通过双if加lock ,就实现了一个懒汉式的单例。
懒汉式 :需要才创建实例,延迟加载
饿汉式 :第一时间创建实例,类加载就马上创建
接下来实现两种饿汉式 的单例
1 静态方法中初始化对象
public class Singleton { private Singleton() //构造私有化,防止外部New { } private static Singleton _singleton = null; //静态构造函数:由CLR保证单例,程序第一次使用这个类型前被调用,且只调用一次 static Singleton() { _singleton = new Singleton(); } //对外提供一个获取实例的方法 public static Singleton CreateInstance() { return _singleton; } }
2 静态字段赋值
public class Singleton { private Singleton() //构造私有化,防止外部New { } //静态字段:在第一次使用这个类之前,由CLR保证,初始化且只初始化一次 private static Singleton _singleton = new Singleton(); //对外提供一个获取实例的方法 public static Singleton CreateInstance() { return _singleton; } }
单例模式创建的实例不会自动释放内存,会长时间占据内存空间。适用场景线程池,数据库连接池,计数器/流水号生成器,配置文件读取,IOC容器。