北龙建设集团有限公司企业网站,保安网站建设,南山商城网站建设多少钱,个人如何做微信下单小程序单例模式
描述 单例模式是一种创建型模式#xff0c;它的目的是确保一个类只有一个实例#xff0c;并提供全局访问点。这个实例可以被多个客户端共享#xff0c;从而避免创建多个实例所带来的资源浪费和不必要的复杂性。 实现
懒汉模式
public class LasySingleton {priv…单例模式
描述 单例模式是一种创建型模式它的目的是确保一个类只有一个实例并提供全局访问点。这个实例可以被多个客户端共享从而避免创建多个实例所带来的资源浪费和不必要的复杂性。 实现
懒汉模式
public class LasySingleton {private volatile static LasySingleton singleton;private LasySingleton(){}public static synchronized LasySingleton createInstance(){if(null singleton){singleton new LasySingleton();}return singleton;}
}
在有些情况下JIT编译器可能会将对象的初始化操作指令重排。我们用使用jdk自带的反编译去查看汇编代码 在JIT编译器进行重排后的顺序会变成以下情况
这种情况下在外界拿到实例对象可能是一个未初始化完成的半成品。 所以需要通过volatile来声明实例从而防止指令重排。 懒汉模式最粗暴的方法是在让实例的创造方法变为同步方法这样能保证实例的唯一性。所有的线程都会被阻塞。阻塞的情况下是非常耗时的我们应该尽可能避免线程阻塞。 实例未创建或者创建都会被阻塞中那么有没有一种方法在对象创建成功后不需要阻塞呢 双重检查锁(DDL) public static LasySingleton createInstanceByDDL() {if (null singleton) {synchronized (LasySingleton.class) {if(null singleton){singleton new LasySingleton();}}}return singleton;}饿汉模式
public class HungrySingleton {private static HungrySingleton singleton new HungrySingleton();private HungrySingleton(){}public static HungrySingleton createInstance(){return singleton;}
}在不受其他干扰的情况这两种模式都能实现单例但是如果我们通过反射去破坏那么单例还能实现吗 反射破坏单例
实现 Testpublic void hungryDestory() throws Exception {ClassHungrySingleton clazz HungrySingleton.class;ConstructorHungrySingleton constructor clazz.getDeclaredConstructor();//使构造方法范围变为publicconstructor.setAccessible(true);HungrySingleton hungrySingleton constructor.newInstance();System.out.println(hungrySingleton);System.out.println(HungrySingleton.createInstance());}Testpublic void lasyDestory() throws Exception {ClassLasySingleton clazz LasySingleton.class;ConstructorLasySingleton constructor clazz.getDeclaredConstructor();//使构造方法范围变为publicconstructor.setAccessible(true);LasySingleton lasySingleton constructor.newInstance();System.out.println(lasySingleton);System.out.println(LasySingleton.createInstance());}实验结果 很容易发现单例模式已经被破坏。那么我们要如何去防止反射破坏呢 我们可以在构造方法中对实例进行判断如果实例已经被创建我们只需要返回那个实例。 解决反射破坏问题
饿汉模式 private HungrySingleton(){if(null singleton){}else {throw new RuntimeException(单例已经存在);}}在进入构造方法前类变量单例已经完成创建。饿汉模式完美解决反射破坏。 懒汉模式无法实现 private LasySingleton() {if(null ! singleton){throw new RuntimeException(单例已经存在);}}懒汉模式在实例创建之前使用反射进行破坏可以创建多个实例无法防止反射破坏。 实现场景
SpringBean容器 ApplicationContext。线程池数据库连接池