1. 单例模式的含义
单例模式是一种常用的软件设计模式,其定义就是只允许一个实例存在。拿Windows操作系统而言,许多时候整个系统只需要一个全局对象,这样更加有利于协同整个系统的行为。为什么这么说呢?我罗列了以下几点:
- 节省资源
我们都知道每当我们去使用new去创建一个实例的时候,那都是要消耗系统的内存资源的。
- 减少不必要性,复杂性
举一个小小的例子,同一个.txt文件它是不被允许被同一个应用程序打开多次显示在窗口上的,那样做也没有必要,不符合逻辑。换一个角度,要是它可以被同一个应用程序打开多次,那就相当于创建了多个实例,这几个实例的内容和第一次打开的内容一摸一样,没有必要。那为了避免出现这种情况的发生,我们就采取了“单例”的这种设计模式。当系统中不存在这个实例时,就创建,反之则不创建。
- 增加安全
它可以很有效的避免多线程访问带来的安全问题。
2. 单例模式的实现
- 饿汉式
通俗的来讲,就是我不管你当前程序要不要我这个实例,在程序初始化时,我就先创建出来。
public class SingleOne{
private static SingleOne singleOne = new SingleOne ();
private SingleOne (){}
public static SingleOne GetSingle(){
return singleOne;
}
}
优点:写法简单,在类装载时就完成实例化。避免了线程同步带来的问题。
缺点:要知道,一个程序中会有很多的类会被实例化,那实例化就会损耗内存资源,这样一上来就造对象的做法,会影响性能。
- 懒汉式
不主动出击,就像一个懒鬼一样,叫到它干活,他才干。
public class SingleTwo {
private static SingleTwo singleTwo ;
private SingleTwo (){}
public static SingleTwo GetSingleTwo (){
// 被动创建,在真正需要使用时才去创建
if (singleTwo == null) {
singleTwo = new SingleTwo ();
}
return singleTwo ;
}
}
优点:能减少内存的损耗,只有在真正需要的时候才会实例化。
缺点:但是这种情况只能在单线程下使用。在多线程中,一旦一个线程刚好进入了if判断语句中,另外一个线程也进去了,哦豁,那就完蛋,还是会产生多个实例。
- 双重加锁机制
public class Single
{
private static Single single;
//程序运行时创建一个静态只读的进程辅助对象
private static readonly object syncRead = new object();
private Single() { }
public static Single GetInstance()
{
//先判断是否存在,不存在再加锁处理
if (single== null)
{
//在同一个时刻加了锁的那部分程序只有一个线程可以进入
lock (syncRead )
{
if (single== null)
{
single= new Single();
}
}
}
return single;
}
}
如上所示,我们进行了两次if 判断检查,使用这种方法无疑是一个非常民智的选择,这样不仅保证了程序在单线程还是多线程都是单例模式,还提高了运行的效率,推荐使用。