- 定义:确保一个类只有一个实例,并提供全局的访问。
例子:项目里数据库访问类。这个类需要全局访问,而且需要使用反射实例化。因为反射很费资源,所以要求只实例化一个实例。这时候使用单例模式正好解决这个问题。
别人写的简单实现的例子
/// <summary> /// 单例模式的实现 /// </summary> public class Singleton { // 定义一个静态变量来保存类的实例 private static Singleton uniqueInstance; // 定义私有构造函数,使外界不能创建该类实例 private Singleton() { } /// <summary> /// 定义公有方法提供一个全局访问点,同时你也可以定义公有属性来提供全局访问点 /// </summary> /// <returns></returns> public static Singleton GetInstance() { // 如果类的实例不存在则创建,否则直接返回 if (uniqueInstance == null) { uniqueInstance = new Singleton(); } return uniqueInstance; } }
当多线程访问的时候,多个线程同时建立实例的时候,因为没有建立过实例,多个线程都会去建立线程。
/// <summary> /// 单例模式的实现 /// </summary> public class Singleton { // 定义一个静态变量来保存类的实例 private static Singleton uniqueInstance; //定义锁 private static readonly object locker=new object(); // 定义私有构造函数,使外界不能创建该类实例 private Singleton() { } /// <summary> /// 定义公有方法提供一个全局访问点,同时你也可以定义公有属性来提供全局访问点 /// </summary> /// <returns></returns> public static Singleton GetInstance() {
//当第一个线程访问的时候加锁。
//当第二个线程访问的时候,就要等待第一个对象解锁才能访问
//lock执行完毕,既第一个对象执行完毕解锁。
lock(locker){ // 如果类的实例不存在则创建,否则直接返回 if (uniqueInstance == null) { uniqueInstance = new Singleton(); } } return uniqueInstance; } }
这样执行,会一直加锁和解锁,很浪费性能。应该避免。
/// <summary> /// 单例模式的实现 /// </summary> public class Singleton { // 定义一个静态变量来保存类的实例 private static Singleton uniqueInstance; //定义锁 private static readonly object locker=new object(); // 定义私有构造函数,使外界不能创建该类实例 private Singleton() { } /// <summary> /// 定义公有方法提供一个全局访问点,同时你也可以定义公有属性来提供全局访问点 /// </summary> /// <returns></returns> public static Singleton GetInstance() { //当第一个线程访问的时候加锁。 //当第二个线程访问的时候,就要等待第一个对象解锁才能访问 //lock执行完毕,既第一个对象执行完毕解锁。 //(双向锁定)当对象为空的时候,执行加锁。 if(uniqueInstance == null){ lock(locker){ // 如果类的实例不存在则创建,否则直接返回 if (uniqueInstance == null) { uniqueInstance = new Singleton(); } } } return uniqueInstance; } }