什么是单例模式?
这里我就不做过多的解释了, 终究关于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保证,在措施第一次使用该类之前被挪用,而且只挪用一次
同静态变量一样, 它会跟着措施运行, 就被实例化, 同静态变量一个原理。