手机网站导航栏特效,网站域名设计方案,wordpress菜单分开间隔,天津塘沽爆炸视频单例模式实现案例 文章目录 单例模式实现案例**饿汉式****枚举饿汉式****懒汉式****双检锁懒汉式****内部类懒汉式** 单例模式概念#xff1a; 单例模式是一种创建型设计模式#xff0c;确保一个类只有一个实例#xff0c;并提供全局访问点。这对于需要在系统中共享某个资源…单例模式实现案例 文章目录 单例模式实现案例**饿汉式****枚举饿汉式****懒汉式****双检锁懒汉式****内部类懒汉式** 单例模式概念 单例模式是一种创建型设计模式确保一个类只有一个实例并提供全局访问点。这对于需要在系统中共享某个资源例如配置信息、数据库连接池等的场景非常有用。
饿汉式Eager Initialization 在类加载时就创建实例线程安全但可能会造成资源浪费。你已经提供了一个经典的饿汉式实现。
懒汉式Lazy Initialization 在需要时才创建实例可能存在线程安全问题需要进行同步处理。你已经给出了懒汉式和双检锁懒汉式的实现其中双检锁懒汉式通过双重检查锁定和volatile关键字确保了线程安全。
枚举单例模式 利用枚举类型的特性天然防止反射和反序列化攻击。你已经提供了一个枚举饿汉式的实现。
静态内部类单例模式 使用静态内部类的方式来延迟加载实例避免了同步问题也能够天然防止反射和反序列化攻击。你已经给出了一个内部类懒汉式的实现。
为什么 DCLDouble-Checked Locking中要使用 volatile 在双检锁懒汉式中volatile关键字确保了可见性和防止指令重排序。如果没有volatile在多线程环境中一个线程可能会看到一个未完全构造的实例导致不正确的结果。
防止反射攻击 在饿汉式和懒汉式中通过在构造方法中加入特定逻辑可以防止反射攻击。在枚举和静态内部类实现中由于它们的特性天然不容易受到反射攻击。
防止反序列化攻击 在饿汉式和懒汉式中通过实现readResolve方法可以防止反序列化攻击。在枚举实现中由于枚举类型的特性不容易受到反序列化攻击。 要求
掌握五种单例模式的实现方式理解为何 DCL 实现时要使用 volatile 修饰静态变量了解 jdk 中用到单例的场景
饿汉式
public class Singleton1 implements Serializable {private Singleton1() {if (INSTANCE ! null) {throw new RuntimeException(单例对象不能重复创建);}System.out.println(private Singleton1());}private static final Singleton1 INSTANCE new Singleton1();public static Singleton1 getInstance() {return INSTANCE;}public static void otherMethod() {System.out.println(otherMethod());}public Object readResolve() {return INSTANCE;}
}构造方法抛出异常是防止反射破坏单例readResolve() 是防止反序列化破坏单例
枚举饿汉式
public enum Singleton2 {INSTANCE;private Singleton2() {System.out.println(private Singleton2());}Overridepublic String toString() {return getClass().getName() Integer.toHexString(hashCode());}public static Singleton2 getInstance() {return INSTANCE;}public static void otherMethod() {System.out.println(otherMethod());}
}枚举饿汉式能天然防止反射、反序列化破坏单例
懒汉式
public class Singleton3 implements Serializable {private Singleton3() {System.out.println(private Singleton3());}private static Singleton3 INSTANCE null;// Singleton3.classpublic static synchronized Singleton3 getInstance() {if (INSTANCE null) {INSTANCE new Singleton3();}return INSTANCE;}public static void otherMethod() {System.out.println(otherMethod());}}其实只有首次创建单例对象时才需要同步但该代码实际上每次调用都会同步因此有了下面的双检锁改进
双检锁懒汉式
public class Singleton4 implements Serializable {private Singleton4() {System.out.println(private Singleton4());}private static volatile Singleton4 INSTANCE null; // 可见性有序性public static Singleton4 getInstance() {if (INSTANCE null) {synchronized (Singleton4.class) {if (INSTANCE null) {INSTANCE new Singleton4();}}}return INSTANCE;}public static void otherMethod() {System.out.println(otherMethod());}
}为何必须加 volatile
INSTANCE new Singleton4() 不是原子的分成 3 步创建对象、调用构造、给静态变量赋值其中后两步可能被指令重排序优化变成先赋值、再调用构造如果线程1 先执行了赋值线程2 执行到第一个 INSTANCE null 时发现 INSTANCE 已经不为 null此时就会返回一个未完全构造的对象
内部类懒汉式
public class Singleton5 implements Serializable {private Singleton5() {System.out.println(private Singleton5());}private static class Holder {static Singleton5 INSTANCE new Singleton5();}public static Singleton5 getInstance() {return Holder.INSTANCE;}public static void otherMethod() {System.out.println(otherMethod());}
}避免了双检锁的缺点
JDK 中单例的体现
Runtime 体现了饿汉式单例Console 体现了双检锁懒汉式单例Collections 中的 EmptyNavigableSet 内部类懒汉式单例ReverseComparator.REVERSE_ORDER 内部类懒汉式单例Comparators.NaturalOrderComparator.INSTANCE 枚举饿汉式单例 大家好我是xwhking一名技术爱好者目前正在全力学习 Java前端也会一点如果你有任何疑问请你评论或者可以加我QQ2837468248说明来意希望能够与你共同进步