单例模式的几种解法
所谓的单例模式,就是我们设计一个类,使这个类每次只能实例化一个对象,即保证该类仅有一个实例。
单例模式的好处有:
1,对唯一实例的受控访问,可以严格控制使用者怎样以及何时去使用它。
2,缩小名字空间,只有一个实例,避免了多个实例名字引起的一些问题,也可看作是对全局变量的一种改进。
3,允许对操作和表示的精化,单例模式的类也有子类,用这个子类的对象来配置一个应用还是比较容易的。
4,允许可变数目的实例
5,比类操作更加灵活
解法一,只适合单线程环境
public sealed class Singleton
{
private Singleton()
{
}
private static Singleton instance = null;
public static Singleton Instance
{
get
{
if (instance == null)
instance = new Singleton();
return instance;
}
}
};
Singleton 的静态属性Instance中,只有在instance 为null的时候才创建一个实例以避免重复创建,该算法只适用于单线程环境
解法二,适合多线程环境,但效率不高
public class sealed class Singleton
{
private Singleton(){}
private static readonly object syncObj = new object();
private static Singleton instance = null;
public static Singleton Instance()
{
get
{
lock(syncObj)
{
if (instance == null)
instance = new Singleton();
}
return instance;
}
}
};
该解法通过加一个同步锁,当一个线程加上同步锁,创建了实例的时候,其他线程只能等待第一个线程释放了这个同步锁才能创建实例,同步锁保证了多线程环境中也只能得到一个实例,但加锁是非常耗时的操作
解法三,适合多线程环境,提高了效率
//加同步锁前后判断实例是否存在
public sealed class Singleton
{
private Singleton()
{
}
private static object syncObj = new object();
private static static Singleton instance = null;
public static Singleton Instance
{
get
{
if (instance == NULL)
{
lock(syncObj)
{
if (instance == NULL)
instance = new Singleton();
}
}
return instance;
}
}
};
该解法通过在加锁之前对实例进行判断,因为当实例已经创建了之后,就不需要进行加锁操作了,该算法既满足了多线程环境中只能得到一个实例,也提高了效率
解法四,高效的解法:适合多线程环境,真正做到了按需创建
//按需创建实例
public sealed class Singleton
{
Singleton()
{
}
public static Singleton instance
{
get
{
return Nested.instance;
}
}
class Nested
{
static Nested()
{}
internal static readonly Singleton instance = new Singleton();
}
};
通过在Sinleton内部定义一个私有类型的Nested,当第一次用到这个嵌套类型的时候,会调用静态构造函数创建的Singleton的实例instance。类型Nested只有在属性Singleton.Instance中被用到,由于奇私有属性他人无法用到,因此我们不调用Singleton的实例时,就不会触发.Net 运行时调用Nested,真正的做到了按需创建