就没必要做多余的行为

时间:2021-09-29 07:37:32

什么是单例模式?

这里我就不做过多的解释了, 终究关于Singleton的资料实在是太多太多了。点击这里

1.简单的思路就是, 创建东西单例的行动转移到此外的行为上面, 操作一个行为去创建东西自身, 如下: 

public class Singleton { private static Singleton _Singleton = null; public static Singleton CreateInstance() { if (_Singleton == null) {
Console.WriteLine("被创建"); _Singleton
= new Singleton(); } return _Singleton; } }

这样写看上去是没有问题, 但是有没有那种可能, 同时两个行动都判断这个东西为空, 那么这个东西就会被创建2次?是的, 多线程中, 这样是无法保证单例。

就没必要做多余的行为

就像这样, 同时创建多个线程去创建这个东西实例的时候, 会被多次创建, 这个时候, 对代码改造一下。

public class Singleton { private static Singleton _Singleton = null; private static object Singleton_Lock = new object(); //锁同步 public static Singleton CreateInstance() { lock (Singleton_Lock) {
            Console.WriteLine("路过");
if (_Singleton == null) {
              Console.WriteLine("被创建"); _Singleton
= new Singleton(); } } return _Singleton; } }

调试代码:

TaskFactory taskFactory = new TaskFactory(); List<Task> taskList = new List<Task>(); for (int i = 0; i < 5; i++) { taskList.Add(taskFactory.StartNew(() => { Singleton singleton = Singleton.CreateInstance(); })); }

功效:

就没必要做多余的行为

上面, 我们创建了多个线程,同时去创建这个东西的实例, 在第二次,东西定名已经被创建了, 尽管只创建了一次满足了我们的需求, 但是我们已知东西被创建了, 还需要进来做不须要的行动吗?

我们都知道, 同步锁为了到达预期的效果, 也是损耗了性能的, 那么下面的输出, 很显然是没须要的行动, 所以我们优化一下。

public class Singleton { private static Singleton _Singleton = null; private static object Singleton_Lock = new object(); public static Singleton CreateInstance() { if (_Singleton == null) //双if +lock
{
lock (Singleton_Lock) { Console.WriteLine("路过。"); if (_Singleton == null) { Console.WriteLine("被创建。"); _Singleton = new Singleton(); } } } return _Singleton; } }

功效:

就没必要做多余的行为

很显然, 这样到达了我们的预期, 东西在被创建后, 就没须要做多余的行为。

操作静态变量实现单例模式

public class SingletonThird { /// <summary> /// 静态变量
/// </summary> private static SingletonThird _SingletonThird = new SingletonThird(); public static SingletonThird CreateInstance() { return _SingletonThird; } }

是不是感受很优雅, 操作静态变量去实现单例,  由CLR保证,,在措施第一次使用该类之前被挪用,而且只挪用一次

PS: 但是他的错误谬误也很明显, 在措施初始化后, 静态东西就被CLR结构了, 哪怕你没用。

操作静态结构函数实现单例模式

public class SingletonSecond { private static SingletonSecond _SingletonSecond = null; static SingletonSecond() {
_SingletonSecond
= new SingletonSecond(); } public static SingletonSecond CreateInstance() { return _SingletonSecond; } }

静态结构函数:只能有一个,无参数的,措施无法挪用 。

同样是由CLR保证,在措施第一次使用该类之前被挪用,而且只挪用一次

同静态变量一样, 它会跟着措施运行, 就被实例化, 同静态变量一个原理。