设计模式之单例模式 DCL双重检测 实例化Volatile防止指令排序 synchronized方法块线程安全 反射安全性问题分析
单例模式之饿汉式模式
- 饿汉式模式来历 直接实例化犹如饿汉子尽快想把饭吃完故称为饿汉式
public class Hungry{
public static final Hungry hungry = new Hungry();
private Hungry(){}
private static final Hungry getInstance{
return hungry;
}
}
单例模式之懒汉式模式
- 懒汉式模式来历 延迟实例化,懒加载故称为懒汉式
public class LayMan{
public static volatile LayMan layMan = null;
private LayMan(){}
//DCL双重检测 + synchronized
private static LayMan getInstance(){
if(layMan!=null){
synchronized (layMan.class){
if(layMan != null){
layMan = new LayMan(); //不是原子的操作,需要在 volatile 防止指令重排序
}
}
}
return layMan;
}
}
单例模式之静态类实现模式
- 静态类单例模式
package com.gof23.single1;
import com.gof23.single.StaticClass;
public class StaticClass1 {
private StaticClass1(){
}
private static class InnerClass{
private static StaticClass1 staticClass1 = new StaticClass1();
}
private static StaticClass1 getInstance(){
return InnerClass.staticClass1;
}
public static void main(String[] args) {
StaticClass1 s1 = StaticClass1.getInstance();
StaticClass1 s2 = StaticClass1.getInstance();
System.out.println(s1 == s2);
}
}
单例模式之枚举类实现模式
- 枚举单例模式
package com.gof23.single;
import sun.security.jca.GetInstance;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
public enum EnumInstance {
INSTANCE;
private static EnumInstance getInstance(){
return INSTANCE;
}
public static void main(String[] args) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
EnumInstance instance1 = EnumInstance.getInstance();
EnumInstance instance2 = EnumInstance.getInstance();
System.out.println(instance1);
System.out.println(instance2);
Constructor constructor = instance1.getClass().getDeclaredConstructor();
constructor.setAccessible(true); //测试反射安全性问题
EnumInstance instance3 = (EnumInstance) constructor.newInstance();
System.out.println(instance3);
}
}
小结: 1. 单例模式都会反射安全性问题,通过反射构造器newInstance会破坏单例模式
2. enum枚举类单例模式不存在反射安全性问题

浙公网安备 33010602011771号