天天看点

单例模式的三种模式

单例模式是设计模式中比较简单的一种模式,也是使用的比较多的一种模式。

特别是在某些对象只需要一个时,比如线程池、缓存、日志对象、注册表对象等。

如果创建了多个,可能会导致很多问题。比如程序行为异常、资源使用过量等。

单例模式确保程序中一个类最多只有一个实例。

单例模式提供访问这个实例的全局点。

在Java中单例模式需要:私有构造器、一个静态方法、一个静态变量。

如果使用多个类加载器,可能会导致单例失效而产生多个实例。

单例模式确保一个类只有一个实例,并提供一个全局的访问点。

  • 下面为延迟加载的单例模式(懒汉式):
/** 
当需要用到对象的时候,再创建对象(延迟加载方式)(一开始是null)第二次直接返回之前创建好的对象,不占内存;
一个线程对象的时候,这种方式线程是安全的;
多个线程对象的时候,这种方式线程是不安全, 可以同步机制处理;
*/
public class Singleton {  
    private static Singleton uniqueInstance;  

    private Singleton() {}  

    public static Singleton getInstance() {  
        if (uniqueInstance == null) {  
            uniqueInstance = new Singleton();  
        }  
        return uniqueInstance;  
    }  
}  
           
  • 处理多线程:需要将getInstance()添加“双重检查加锁”,多线程的问题就可以轻松解决。
/**
    解决多线程不安全问题
*/
public class Girl {
    //创建本类对象的引用
    private static Girl g = null;
    //构造方法私有
    private Girl(){
    }
    //提供一个公共的方法让外界访问,获取到已创建的本类对象
    //第一次访问该方法,创建对象
    //之后再访问该方法,返回以前创建好的对象
    public static Girl getInstance(){
        //第一次访问该方法,创建对象
        if (g == null) {
            synchronized(Girl.class){
                if (g == null) {
                    g = new Girl();
                }
            }
        }
        //之后再访问该方法,返回以前创建好的对象
        return g;
    }
}
           
  • 如果应用程序总是创建并使用单例模式、或者在创建和运行时负担不太繁重,可以急切创建实例(饿汉式):
/**
    直接创建对象,这样是线程安全的
*/
public class Singleton {  
    private static Singleton uniqueInstance = new Singleton();  

    private Singleton() {}  

    public static synchronized Singleton getInstance() {  
        return uniqueInstance;  
    }  
}