单例模式要求在应用运行的过程中,只有一个类的实例存在。因此,要确保创建过程是线程安全的,同时要兼顾性能。目前了解到做得比较好的,就是这种initialization on demand holder模式(简称holder模式)。holder模式巧妙使用虚拟机的类加载和初始化机制来实现延迟加载和保证创建过程线程安全。
首先看下holder模式:
public class BestSingleton {
//构造方法一定要设为private
private BestSingleton(){}
private static class LazyLolder{
private static BestSingleton INSTANCE = new BestSingleton();
}
public static BestSingleton getInstance(){
return LazyLolder.INSTANCE;
}
}
然后,分析运行 BestSingleton.getInstance()语句的过程:
- ClassLoader加载BestSingleton类,并初始化,由于BestSingleton类不存在任何域,初始化看起来没有做任何事。
- 调用BestSingleton类的getInstance()方法,至此,LazyLolder类的调用第一次出现。因为调用的是一个静态域,因此要执行LazyLolder类的静态初始化。
- 静态初始化LazyLolder类,也就是对INSTANCE 变量进行初始化,实例化一个BestSingleton类的实例,并赋值给INSTANCE 。
- 继续执行getInstance()方法的返回语句。
关键是在第三步,jvm对类的初始化过程是一个串行,单线程的过程,所以不会有并发的问题。