单件模式
常常用来管理共享的资源,注册表设置对象,数据库连接,线程池
单件模式:确保一个类只有一个实例,并提供一个全局访问点。
public class Singleton{
private static Singleton uniqueInstance;
//私有构造函数
private Singleton(){}
//静态方法
public static Singleton getInstance()
{
if(uniqueInstance == null)
{
uniqueInstance = new Singleton();
}
return uniqueInstance;
}
}
多线程需要获取单例时,可能会存在问题,会产生多个对象。
处理多线程的方法:
只要把getInstance()变成同步方法,多线程灾难几乎就可以轻易解决了。
public class Singleton{
private static Singleton uniqueInstance;
//私有构造函数
private Singleton(){}
//静态方法
public static synchronized Singleton getInstance()
{
if(uniqueInstance == null)
{
uniqueInstance = new Singleton();
}
return uniqueInstance;
}
}
但是 同步getInstance()的做法将会拖垮性能,要知道同步一个方法可能造成程序执行效率下降100倍。
有如下几种方案:
1、如果你的应用程序可以接受同步getInstance()造成的额外负担,就不要做额外的处理了。毕竟同步getInstance()的
方法既简单又有效。
2、使用“急切”创建实例,而不用延迟实例化的做法
如果应用程序总是创建并使用单件实例,或者在创建和运行时方面的负担不太繁重,可以使用此方法。
public class Singleton{
private static Singleton uniqueInstance = new Singleton();
//私有构造函数
private Singleton(){}
//静态方法
public static Singleton getInstance()
{
return uniqueInstance;
}
}
利用这个做法,我们依赖JVM在加载这个类时马上创建此唯一的单件实例。
JVM保证在任何线程访问uniqueInstance静态变量之前,一定先创建此实例。
3、
用“双重检查枷锁”,在getInstance()中减少使用同步
public class Singleton{
private volatile static Singleton uniqueInstance;
//私有构造函数
private Singleton(){}
//静态方法
public static Singleton getInstance()
{
if(uniqueInstance == null)
{
synchronized(Singleton.class){
if(uniqueInstance == null)
{
uniqueInstance = new Singleton();
}
}
}
return uniqueInstance;
}
}
volatile关键字确保,当uniqueInstance变量被初始化成Singleton实例时,多个线程正确地处理uniqueInstance变量。
如果性能是关心的重点,那么这个做法可以帮助你大大减少getInstance()的时间消耗。
note:
如果使用多个类加载器,可能导致单件类失效而产生多个实例。