**主要从两个方面考虑这个问题
- 从无所编程的角度出发,利用CAS
- 利用JVM首次加载类的机制
1.利用静态变量初始化的饿汉式模式
public class singleton03 {
private static singleton03 instance = new singleton03();
private singleton03() {
}
public static singleton03 getInstance() {
return instance;
}
}
2.利用枚举
public enum Singleton7 {
INSTANCE;
}
通过javap -c Singleton7.class 反编译字节码文件可以看到
public final class cn.roy.design.Singleton7 extends java.lang.Enum<cn.roy.design.Singleton7> {
public static final cn.roy.design.Singleton7 INSTANCE;
public static cn.roy.design.Singleton7[] values();
Code:
0: getstatic #1 // Field $VALUES:[Lcn/roy/design/Singleton7;
3: invokevirtual #2 // Method "[Lcn/roy/design/Singleton7;".clone:()Ljava/lang/Object;
6: checkcast #3 // class "[Lcn/roy/design/Singleton7;"
9: areturn
public static cn.roy.design.Singleton7 valueOf(java.lang.String);
Code:
0: ldc #4 // class cn/roy/design/Singleton7
2: aload_0
3: invokestatic #5 // Method java/lang/Enum.valueOf:(Ljava/lang/Class;Ljava/lang/String;)Ljava/lang/Enum;
6: checkcast #4 // class cn/roy/design/Singleton7
9: areturn
static {};
Code:
0: new #4 // class cn/roy/design/Singleton7
3: dup
4: ldc #7 // String INSTANCE
6: iconst_0
7: invokespecial #8 // Method "<init>":(Ljava/lang/String;I)V
10: putstatic #9 // Field INSTANCE:Lcn/roy/design/Singleton7;
13: iconst_1
14: anewarray #4 // class cn/roy/design/Singleton7
17: dup
18: iconst_0
19: getstatic #9 // Field INSTANCE:Lcn/roy/design/Singleton7;
22: aastore
23: putstatic #1 // Field $VALUES:[Lcn/roy/design/Singleton7;
26: return
}
本质就是饿汉式 + static代码块
- 利用CAS实现单例模式
public class Singleton06 {
private static final AtomicReference<Singleton06> INSTANCE = new AtomicReference<Singleton06>();
private static Singleton06 instance;
private Singleton06() {
}
public static Singleton06 getInstance() {
for (; ; ) {
Singleton06 instance = INSTANCE.get();
if (null != instance){
return instance;
}
INSTANCE.compareAndSet(null, new Singleton06());
return INSTANCE.get();
}
}
}
4.利用静态内部类优化饿汉式
public class Singleton04 {
private static class SingletonHolder {
private static Singleton04 instance = new Singleton04();
}
private Singleton04() {
}
public static Singleton04 getInstance() {
return SingletonHolder.instance;
}
}