学习/背诵目标:线程安全的;饿汉式、懒汉式
如果是线程不安全的/非线程安全的,直接跳过吧,没用
需求:单例模式必须要对外提供 getInstance()
函数
饿汉式和懒汉式的定义、区别
饿汉式/饥饿模式:instance
在类装载时就实例化
懒汉式/懒惰模式:instance
在首次调用 getInstance()
时就实例化
以下两种写法不需要加锁,由 JVM 保证单例模式的正确性,所以看起来用了魔法
线程安全+饿汉式
/**
* 饿汉式: 类加载时就初始化
*/
/** final 不能被继承 */
final class HungrySingleton {
/** 在 static 变量中保存实例对象 */
public static final HungrySingleton instance = new HungrySingleton();
/** 禁用构造方法 */
private HungrySingleton() {}
/**
* 获取单例对象, 直接返回已创建的实例
*/
public static HungrySingleton getInstance() {
return instance;
}
}
线程安全+懒汉式,这种写法叫登记式/静态内部类
/**
* 懒汉式: 类加载时就初始化
*/
public class LazySingleton {
/** 静态内部类中,static final 变量持有外部类的实例 */
private static class SingletonHolder {
private static final LazySingleton instance = new LazySingleton();
}
/** 禁用构造方法 */
private LazySingleton() {}
/**
* 获取单例对象, 首次调用时创建实例,注意函数 final
*/
public static final LazySingleton getInstance() {
return SingletonHolder.instance;
}
}
扩展知识点:双重校验锁实现懒汉式(synchronized + volatile 细节);ThreadLocal;enum 实现饿汉式+防止反射、反序列化破坏单例+限制不能继承Enum以外的类
后续学懂了再更新 :)