线程安全下的单例模式

    技术2022-07-10  99

    关键字:后端开发,设计模式,Java。

    单线程的单例

    私有构造方法 持有自己类的静态私有属性 获取自己类实例的静态方法 多线程场景下是不安全的

    多线程下线程安全的单例

    私有构造方法 持有自己类的私有属性 获取自己类实例的方法 synchronized 同步,线程安全的关键

    绝对线程安全的单例(官方推荐使用)

    私有构造方法,枚举默认其实就是私有的 获取自己类实例的静态方法 内部枚举类

    单例模式有多种实现方式,但是,有三个相同的特点:

    构造器私有,防止外部new对象 含持有自己类型的属性; 对外提供获取实例的静态方法;

    使用场景:

    工具类,比如获取所有城市的工具方法; 创建对象需要消耗资源的类

    拓展知识

    通过反射技术可以破坏除枚举单例以外的其他单例模式。 控制台结果输出为:

    枚举类绝对线程安全的原因分析:

    枚举类型的最终反编译源码:

    public final class T extends Enum { private T(String s, int i) { super(s, i); } public static T[] values() { T at[]; int i; T at1[]; System.arraycopy(at = ENUM$VALUES, 0, at1 = new T[i = at.length], 0, i); return at1; } public static T valueOf(String s) { return (T)Enum.valueOf(demo/T, s); } public static final T SPRING; public static final T SUMMER; public static final T AUTUMN; public static final T WINTER; private static final T ENUM$VALUES[]; static { SPRING = new T("SPRING", 0); SUMMER = new T("SUMMER", 1); AUTUMN = new T("AUTUMN", 2); WINTER = new T("WINTER", 3); ENUM$VALUES = (new T[] { SPRING, SUMMER, AUTUMN, WINTER }); } }

    通过反编译后代码我们可以看到,public final class T extends Enum,说明,该类是继承了Enum类的,同时final关键字告诉我们,这个类也是不能被继承的。当我们使用enmu来定义一个枚举类型的时候,编译器会自动帮我们创建一个final类型的类继承Enum类,所以枚举类型不能被继承,我们看到这个类中有几个属性和方法。

    而且所有的成员变量和成员方法都是static类型的,因为static类型的属性会在类被加载之后被初始化,当一个Java类第一次被真正使用到的时候静态资源被初始化、Java类的加载和初始化过程都是线程安全的。所以,创建一个enum类型是线程安全的。

    Processed: 0.015, SQL: 9