设计模式之单例模式学习(C#)

时间:2021-09-10 08:16:48

最近在换工作,发现面试都会问到设计模式中的单例模式,所以回家做了一个对于单例模式的总结,如有问题,请留言指教。

单例模式的简介

单例模式:就是保证系统中只有一个实例,就叫单例模式(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