单例模式实战标准上手
背景
在之前的文章中有做过单例模式的介绍,介绍了单线程单例和多线程单例以及其应用条件
-
饿汉模式在类被初始化时就已经在内存中创建了对象,用空间换时间,不存在线程安全问题。
-
懒汉模式在方法被调用后才创建对象,用时间换空间,在多线程环境下存在风险。所以也有双重锁懒汉的补救方法,但也存在风险。
今天介绍一种平时在实战中比较常用的一劳永逸的写法—静态内部类单例
实战
构造方法
public class SingleTon {
private SingleTon(){ /* 构造函数 */}
private final static class SingleTonHolder {
private final static SingleTon Instance = new SingleTon();
}
public static SingleTon getInstance() {
return SingleTonHolder.Instance;
}
public void do() {
System.out.println("doSomething");
}
}
使用方法
import com.you.place.SingleTon;
public class Demo {
public void callSingleTonMethod() {
SingleTon.getInstance().do(); // 使用时用SingleTon.getInstance()进行实例的调用
}
}
静态内部类的优点:
- 外部类加载时并不需要立即加载内部类,内部类不被加载则不去初始化INSTANCE,故而不占内存(懒汉优点)。
- 当getInstance()方法第一次被调用时,才会去初始化INSTANCE,第一次调用getInstance()方法才加载InstanceDemoHolder类,这种方法不仅能确保线程安全(饿汉优点),也能保证单例的唯一性,同时也延迟了单例的实例化。
静态内部类的缺点:
- 单元测试的时候,由于使用了私有内部类和static和final修饰,这使得mock它变得几乎不可能,这使得它的可测试度下降了。
- 由于使用静态内部类的形式去创建单例,所以当需要传参数或反射获取的时候会变得异常困难。