本文介绍四种单例模式的写法,以及各个模式的优缺点。
单例模式介绍单例模式保证类只被实例化一次(new 一次),并提供一个访问它的全局访问点 单例模式的几个注意点
- 私有化构造方法提供获取实例的方法能安全的创建出实例
public class Singleton1 {
// 类加载时创建实例
private static final Singleton1 INSTANCE = new Singleton1();
// 私有化构造方法
private Singleton1() {}
public static Singleton1 getInstance() {
return INSTANCE;
}
}
总结
一般不用这种方式,B格不够本方式简单有效、代码量少、对性能不高的系统可以使用饿汉式性能最差 二. 双重检查(doubleCheck)懒汉式
public class Singleton2 {
private Singleton2() {}
// doubleCheck 使用 volatile 避免指令重排
private static volatile Singleton2 INSTANCE = null;
public static Singleton2 getInstance() {
// 第一次检查
if (INSTANCE == null) {
synchronized (Singleton2.class) {
// 第二次检查
if (INSTANCE == null) {
INSTANCE = new Singleton2();
}
}
}
return INSTANCE;
}
}
总结
这种方式常用注意指令重排 三. 静态内部类方式(懒汉式)
public class Singleton3 {
private Singleton3() {}
private static class LazyHolder {
// 静态内部类加载时创建对象
private static final Singleton3 INSTANCE = new Singleton3();
}
public static Singleton3 getInstance() {
// Java使用到LazyHolder时才会加载LazyHolder,加载LazyHolder才会出发对象的创建
return LazyHolder.INSTANCE;
}
}
总结
常用方式建议使用这种方式(代码量最少,性能又高) 四. 枚举类方式(懒汉式)
class Singleton4 {
private Singleton4() {}
public static Singleton4 getInstance() {
return Singleton.INSTANCE.getInstance();
}
private enum Singleton {
INSTANCE;
private final Singleton4 singleton;
// JVM 保证这个方法只被调用一次
Singleton() {
singleton = new Singleton4();
}
public Singleton4 getInstance() {
return singleton;
}
}
}
总结
不常用、不建议使用面试用,装B用了解过虚拟机的小伙伴应该知道,枚举其实只是语法糖,会被编译为 final static 的类 总结
首选 静态内部类方式(懒汉式) 方式。次选 懒汉式 doubleCheck 方式。其他两种了解即可。
码云完整代码跳转



