1、为什么要用单例模式?
我说一个在上位机软件开发领域一定会用到单例模式的场景,当我们使用运动控制卡控制轴的时候,一般情况下都会写两种模式,一种是自动模式,一种是手动模式,自动模式和手动模式都是对同一张控制卡操作,所以我们一般会将控制卡的操作封装到一个类中,并且控制卡一般都是获取唯一的句柄,我们拿到这个句柄对控制卡进行操作,这时候就不允许我们使用一个类的多个对象去访问控制卡了,所以我们需要在自动模式和手动模式下都使用控制卡类的同一个对象,这时候单例模式就派上用场了。基于以上原因,我们可以得出使用一个实例的两大原因:
1)使用一个实例,避免了系统因创建多个实例造成的资源浪费;
2)使用一个实例,避免了多个状态对用户造成干扰保证了系统状态的唯一性,也就是一个类只能有一个实例。
2、怎么使用单例模式?
我们知道了要保证一个类的实例只有一个并且易于访问,那么可以让这个类自己去创建并保存实例以避免在别的地方创建,并将这个类的实例声明为静态的,因为静态变量可以帮我们实现全局访问的效果,为了让该实例跨类访问,再将该实例的访问修饰符设置为public,代码如下:
单例类定义:
class singleton
{
private static singleton instance = null; //静态私有成员变量,防止instance在类的外部被实例化
private singleton()//私有构造函数,避免类在外部实例化
{
}
public static singleton GetInstance()//静态公有方法,给类的外部调用,并返回唯一的实例。
{
if (instance == null)
instance = new singleton();
return instance;
}
}
调用:
singleton singleton1= singleton.GetInstance();
3、多线程下的单例模式
上一节介绍的单例写法是不支持多线程环境下使用的,本节介绍如何创建可以在多线程环境下使用的单例
1)饿汉式单例
单例类定义:
class singleton
{
private static singleton instance = new singleton ();
private singleton()
{
}
public static singleton GetInstance()
{
return instance;
}
}
调用:
singleton singleton1= singleton.GetInstance();
优点:可避免多线程下创建多个实例;
缺点:延长了初始化的时间;
2)懒汉式单例
单例类定义:
class singleton
{
private static singleton instance = null;
private static readonly object syncBlock=new object ();
private singleton()
{
}
public static singleton GetInstance()//双重锁,避免多线程下创建多个实例
{
if(instance ==null)
{
lock (syncBlock )
{
if(instance ==null )
{
instance = new singleton();
}
}
}
return instance;
}
}
调用:
singleton singleton1= singleton.GetInstance();
4、多例模式
多例类定义:
class singleton
{
private static singleton instance1 = null;
private static singleton instance2 = null;
private static readonly object syncBlock1 = new object();
private static readonly object syncBlock2 = new object();
private singleton()
{
}
public static singleton GetInstance(int instanceIndex)//双重锁,避免多线程下创建多个实例
{
if (instanceIndex == 1)
{
if (instance1 == null)
{
lock (syncBlock1)
{
if (instance1 == null)
{
instance1 = new singleton();
}
}
}
return instance1;
}
else
{
if (instance2 == null)
{
lock (syncBlock2)
{
if (instance2 == null)
{
instance2 = new singleton();
}
}
}
return instance2;
}
}
}
调用:
singleton singleton1= singleton.GetInstance(1);
singleton singleton2= singleton.GetInstance(2);
以上内容参考《C#设计模式》第2版,刘伟,另单例模式这一章的习题6、7我分别写了对应的demo。习题6、7两个设计模式的demo