单例模式
懒汉式
使用时加载,对内存资源消耗低,调用的效率低。
线程不安全
public class lazySingleton1 {
private static lazySingleton1 instance;
// 私有构造函数
private lazySingleton1() {
}
// 静态工厂方法
public static lazySingleton1 getInstance() {
if (instance == null) {
instance = new lazySingleton1();
}
return instance;
}
}
线程安全
public class lazySingleton2 {
private static lazySingleton2 instance;
private lazySingleton2() {
}
public static synchronized lazySingleton2 getInstance() {
if (instance == null) {
instance = new lazySingleton2();
}
return instance;
}
}
饿汉式
初始化时就创建对象单例,使用时直接返回,容易照成资源浪费。基于类加载机制,避免了多线程同步问题。
public class hungrySingleton {
private static hungrySingleton instance = new hungrySingleton();
private hungrySingleton() {
}
public static hungrySingleton getInstance() {
return instance;
}
}
双重校验锁
能够做到效率和安全的双重保证,单例在第一次使用时创建。使用 volatile + 双重检测机制 -> 禁止指令重排。
public class DoubleLockSingleton {
// volatile + 双重检测机制 -> 禁止指令重排
private volatile static DoubleLockSingleton instance;
private DoubleLockSingleton() {
}
// 1、memory = allocate() 分配对象的内存空间
// 2、ctorInstance() 初始化对象
// 3、instance = memory 设置instance指向刚分配的内存
public static DoubleLockSingleton getInstance() {
if (instance == null) {
synchronized (DoubleLockSingleton.class) {
if (instance == null) {
instance = new DoubleLockSingleton();
}
}
}
return instance;
}
}
静态内部类
利用了类加载机制 -> 天然的单例,线程安全,调用效率高,可以延时加载。
public class InnerClassSingleton {
private static class SingletonHolder {
private static final InnerClassSingleton INSTANCE =
new InnerClassSingleton();
}
private InnerClassSingleton() {
}
public static InnerClassSingleton getInstance() {
return SingletonHolder.INSTANCE;
}
}
枚举类
最安全的单例模式。枚举类本身就是单例,可以避免多线程同步问题。同时可以防止反射与反序列化重新创建新的对象,在调用时初始化。
public enum EnumSingleton {
INSTANCE;
// whatever method
public void anyMethod() {
}
}