单例模式是什么
简单来说,一个对象只有一个实例,称为单例模式。
什么情况用到单例模式
在开发过程中有很多情景需要用到单例模式,例如:线程池、缓存、对话框、日志对形象等等,这些对象只能有一个实例,如果制造出多个实例,可能会导致程序的行为异常、资源使用过量、或者是不一致的结果。
怎么样使用单例模式
简单的单例模式
public class Singletion
{
private static Singletion instanceSingletion;
private Singletion ()
{
}
public static Singletion getInstance()
{
if(instanceSingletion==null){
instanceSingletion=new Singletion();
}
return instanceSingletion;
}
}
Singletion 对象利用一个静态变量来记录Singletion 类的唯一实例,把构造器声明为私有的,只有Singletion 类内才可以调用构造器。
多线程下的单例
上面的getInstance方法创建Singletion使用了延迟实例化的做法,这在多线程下使用会造成灾难。只需把getInstance变成同步(synchronized)方法,迫使每个线程进入这个方法时是在其他线程离开该方法之后。
public static synchronized Singletion getInstance()
{
if(instanceSingletion==null){
instanceSingletion=new Singletion();
}
return instanceSingletion;
}
但这个方案有一点不好,同步会降低性能,在不想牺牲应用程序接受额外的负担,这个方案的确有点不适合。在应用程序启动时就创建此单例,就不用延迟实例化的做法了。
public class Singletion
{
private static Singletion instanceSingletion=new Singletion() ;
private Singletion ()
{
}
public static synchronized Singletion getInstance()
{
return instanceSingletion;
}
}
这个做法,JVM保证任何线程访问instanceSingletion静态变量之前,一定会创建实例,但这就控制不了什么时候创建这个对象。还有一种方案,利用双重检查加锁在getInstance中减少使用同步。
public class Singletion
{
private volatile static Singletion instanceSingletion;
private Singletion ()
{
}
public static synchronized Singletion getInstance()
{
if(instanceSingletion==null){
synchronized (Singletion.class)
{
if(instanceSingletion==null)
{
instanceSingletion=new Singletion();
}
}
}
return instanceSingletion;
}
}
首先判断instanceSingletion是否已经创建,如果还没创建才会进行同步,这样只有第一次才会同步,这就不会牺牲到性能了。(volatile关键字是java5后才出现,在这里的作用是,当instanceSingletion变量被初始化成Singletion实例时,多个线程正确地处理instanceSingletion变量)