一. 静态内部类懒加载
/**
* 使用静态内部类懒加载
*/
class Singleton1 {
private Singleton1() {}
private static class Singleton1Container{
private static Singleton1 instance = new Singleton1();
}
public static Singleton1 getInstance() {
return Singleton1Container.instance;
}
}
二. 双重检查锁配合volatile关键字
懒加载、双重检查使得只有初次初始化时才加锁,提高效率,使用volatile关键字禁止指令重排列
volatile参考:Java中的双重检查锁(double checked locking)
/**
* 双重检查锁
* 实现懒加载,避免每次获取实例时都要加锁提高效率
* 使用volatile可以禁止指令重排
* 因为 instance= new Singleton2() 并非是一个原子操作,
* 事实上,在 JVM 中上述语句至少做了以下这 3 件事:
* 第一步是给instance分配内存空间;
* 第二步开始调用 DSingleton2的构造函数等,来初始化instance;
* 第三步,将 instance 对象指向分配的内存空间(执行完这步 instance 就不是 null 了)。
* 这里需要留意一下 1-2-3 的顺序,因为存在指令重排序的优化,也就是说第 2 步和第 3 步的顺序是不能保证的,
* 最终的执行顺序,可能是 1-2-3,也有可能是 1-3-2
*/
class Singleton2 {
private static volatile Singleton2 instance = null;
public static Singleton2 getInstance() {
if (instance == null) {
synchronized (Singleton2.class) {
if (instance == null) {
instance = new Singleton2();
}
}
}
return instance;
}
}