饿汉式
public class Hunger {
private Hunger() {
}
private static Hunger singleton = new Hunger();
public static Hunger getSingleton() {
return singleton;
}
}
懒汉式
volatile + double check
public class LazyTwo {
private static volatile LazyTwo singleton = null;
/*
实例化对象的步骤
1. memory = allocate() 分配对象的内存空间
2. ctorInstance() 初始化对象
3. instance = memory 设置 instance 指向刚刚分配的内存
当多线程的时候,可能会指令重排
例如线程A由于指令重排,导致步骤2和3互换,在进行了1、3、2,假设此时还在初始化对象
此时线程B进来,直接判断 instance 不为 null,就直接返回了 instance
此时的 instance 指向的内存还没有初始化完毕,如果贸然使用,可能出问题
所以用 volatile 修饰对象,禁止对象的创建进行指令重排
*/
public static LazyTwo getInstance() {
if (singleton == null) {
synchronized (LazyTwo.class) {
if (singleton == null) {
System.out.println("初始化");
singleton = new LazyTwo();
}
}
}
return singleton;
}
}
单例
public class SingleEnum {
private SingleEnum() {
}
private SingleEnum instance;
public static SingleEnum getInstance() {
return Singleton.INSTANCE.getSingleEnum();
}
private enum Singleton {
INSTANCE;
private SingleEnum singleEnum;
// JVM 保证单例
Singleton() {
singleEnum = new SingleEnum();
}
public SingleEnum getSingleEnum() {
return singleEnum;
}
}
}