设计模式-单例模式
单例模式(创建型)
说明:一个类只能创建一个对象。
主要解决:一个全局使用的类频繁地创建与销毁。
java中的应用 :java.lang.RunTime
java.awt.Desktop
org.springframework.beans.factory.config.AbstractFactoryBean
org.apache.ibatis.executor.ErrorContext
1.饿汉模式
import lombok.SneakyThrows; import java.io.*; import java.lang.reflect.Constructor; public class HungrySingleton implements Serializable,Cloneable{ private final static HungrySingleton hungrySingleton; static{ hungrySingleton = new HungrySingleton(); } private HungrySingleton(){ if(hungrySingleton != null){ throw new RuntimeException("单例构造器禁止反射调用"); } } public static HungrySingleton getInstance(){ return hungrySingleton; } // private Object readResolve(){ return hungrySingleton; } @Override protected Object clone() throws CloneNotSupportedException { // return super.clone(); return getInstance(); } @SneakyThrows public static void main(String[] args) { HungrySingleton hungrySingleton = HungrySingleton.getInstance(); // 调用父类的clone 方法会产生不同的对象 HungrySingleton clone = (HungrySingleton)hungrySingleton.clone(); System.out.println(hungrySingleton == clone); // false // 反射破坏 Constructor<HungrySingleton> constructor = HungrySingleton.class.getDeclaredConstructor(); constructor.setAccessible(true); HungrySingleton reflect = constructor.newInstance(); System.out.println(hungrySingleton == reflect); // 序列化破坏 ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("singleton_file")); oos.writeObject(hungrySingleton); File file = new File("singleton_file"); ObjectInputStream ois = new ObjectInputStream(new FileInputStream(file)); HungrySingleton serializable = (HungrySingleton)ois.readObject(); System.out.println(hungrySingleton == serializable); } }
2.懒汉模式
public class LazySingleton { private static LazySingleton lazySingleton = null; private LazySingleton(){ if(lazySingleton != null){ throw new RuntimeException("单例构造器禁止反射调用"); } } public synchronized static LazySingleton getInstance(){ if(lazySingleton == null){ lazySingleton = new LazySingleton(); } return lazySingleton; } }
3.双检锁模式
public class LazyDoubleCheckSingleton { private volatile static LazyDoubleCheckSingleton lazyDoubleCheckSingleton = null; private LazyDoubleCheckSingleton(){ } public static LazyDoubleCheckSingleton getInstance(){ if(lazyDoubleCheckSingleton == null){ synchronized (LazyDoubleCheckSingleton.class){ if(lazyDoubleCheckSingleton == null){ lazyDoubleCheckSingleton = new LazyDoubleCheckSingleton(); //1.分配内存给这个对象 // //3.设置lazyDoubleCheckSingleton 指向刚分配的内存地址 //2.初始化对象 // intra-thread semantics // ---------------//3.设置lazyDoubleCheckSingleton 指向刚分配的内存地址 } } } return lazyDoubleCheckSingleton; } }
4.静态内部类
public class StaticInnerClassSingleton { private static class InnerClass{ private static StaticInnerClassSingleton staticInnerClassSingleton = new StaticInnerClassSingleton(); } public static StaticInnerClassSingleton getInstance(){ return InnerClass.staticInnerClassSingleton; } private StaticInnerClassSingleton(){ if(InnerClass.staticInnerClassSingleton != null){ throw new RuntimeException("单例构造器禁止反射调用"); } } }
5.枚举模式
public enum EnumInstance { INSTANCE; protected void printTest(){ System.out.println("do something"); }; }
6.容器单例模式
public class ContainerSingleton { private ContainerSingleton(){ } private static Map<String,Object> singletonMap = new HashMap<String,Object>(); public static void putInstance(String key,Object instance){ if(StringUtils.isNotBlank(key) && instance != null){ if(!singletonMap.containsKey(key)){ singletonMap.put(key,instance); } } } public static Object getInstance(String key){ return singletonMap.get(key); } }
7.线程级单例ThreadLocal
public class ThreadLocalInstance { private static final ThreadLocal<ThreadLocalInstance> threadLocalInstanceThreadLocal = new ThreadLocal<ThreadLocalInstance>(){ @Override protected ThreadLocalInstance initialValue() { return new ThreadLocalInstance(); } }; private ThreadLocalInstance(){ } public static ThreadLocalInstance getInstance(){ return threadLocalInstanceThreadLocal.get(); } }