最近在换工作,发现面试都会问到设计模式中的单例模式,所以回家做了一个对于单例模式的总结,如有问题,请留言指教。
单例模式的简介
单例模式:就是保证系统中只有一个实例,就叫单例模式(singleton pattern);
单例模式分为:饿汉式和懒汉式;
单例模式必须遵循的规则:
1. 该类,在整个系统中必须只能有一个实例;
2. 这个唯一的实例,必须类自行创建这个实例;
3. 必须自行向整个系统提供这个实例;
单例模式具体实现必须遵循的规则:
1. 定义一个静态变量来保存实例;
2. 定义一个私有的构造函数,阻止外界自己创建实例;
3. 定义一个静态公有方法,提供一个全局的访问点;
4. 考虑到线程安全时,需要定义一个标识,确保线程同步机制;
单例模式的典型的应用代码:
饿汉式
饿汉式,不用考虑在用户给实例赋值null时,出问题.因为每次进去都会实例化;
public class Singleton { private static Sinleton mySingleton=new Sinleton(); private Sinleton { } public static Sinleton GetIntance() { return mySinleton; } }
View Code懒汉式
public class Singleton { private static Singleton mySingleton; private Singleton { } public static Singleton GetIntance() { if(mySingleton==null) { return mySingleton=new Singleton(); } return mySingleton; } }
View Code单例模式多线程情况
针对懒汉式,多线程下出现这种情况:比如两线程A和B,A运行到if(mySingleton==null) 时,B运行到mySingleton=new Singleton();B虽然实例化了mySingleton,但是对于A还是没有被实例化,A继续会执行 mySingleton=new Singleton();这个时候就出现问题了 ,有两个实例的问题;于是改编代码
public class SingletonExample { private static SingletonExample mySingleton; private static readonly object locker=new object(); private SingletonExample { } //该公有访问方法,可以重载多参数的方法; public static SingletonExample GetInstance() { if(mySingleton==null) { lock(locker) { mySingleton=new SingletonExample(); } } return mySingleton; } }
View Code此时,A,B同时运行到lock(locker) ,这时只能一个线程访问,于是B先执行,B获得锁,然后B执行完后,解锁. A执行去,因为没有判断是否mySingleton==null,所以还是会实例化,出现两个实例的情况;
于是双重检查模式(DCL)就出现了。代码如下:
public class SingletonExample
{
//此处是懒汉式; 未实例化 ,比较常用.
//饿汉式: private static SingletonExample mySingleton =new SingletonExample(); //已实例化
private static SingletonExample mySingleton;
private static readonly object locker=new object();
private SingletonExample()
{
}
//该公有访问方法,可以重载多参数的方法;
public static SingletonExample GetInstance()
{
if(mySingleton==null)
{
lock(locker)
{
if(mySingleton==null)
{
mySingleton=new SingletonExample();
}
}
}
return mySingleton;
}
}
注意:
1.因为实现单例模式的这个实际是一个类,所以除了遵循了单例该有的规则,其他的字段,属性都和普通类一样都可以存在;
关于单例模式的基础学习就是以上,有问题,请留言互相讨论;THX
,