电脑网站首页设计,网站总体设计,滨河网站建设,做业精灵官方网站介绍什么是单例模式#xff1a;保证一个类仅有一个实例#xff0c;并提供一个访问它的全局访问点解决什么问题#xff1a;省略创建对象所花费的时间#xff0c;不需要频繁创建对象#xff0c;减轻 GC 压力。单例模式有以下几种实现方式#xff1a;懒汉式第一次使用的时候…介绍什么是单例模式保证一个类仅有一个实例并提供一个访问它的全局访问点解决什么问题省略创建对象所花费的时间不需要频繁创建对象减轻 GC 压力。单例模式有以下几种实现方式懒汉式第一次使用的时候才进行加载// 非线程安全public class Singleton {private Singleton(){}private static Singleton singleton;public static Singleton getSingleton(){if (singleton null){singleton new Singleton();}return singleton;}}// 加锁线程安全但是每次获取都会加锁判断public class Singleton {private Singleton(){}private static Singleton singleton;public static synchronized Singleton getSingleton(){if (singleton null){singleton new Singleton();}return singleton;}}饿汉式在类加载时就完成了初始化所以类加载较慢但获取对象的速度快。通过类加载机制保证单例但是如果代码中有其它方式导致类加载(反射、反序列化)就不满足单例public class Singleton {public static Singleton singleton new Singleton();private Singleton(){}public static getSingleton() {return singleton;}}双重校验(double check)public class Singleton {private Singleton(){}public static volatile Singleton singleton;public static getSingleton(){if (singleton null){synchronized(Singleton.class){if (singleton null){singleton new Singleton();}}}return singleton;}}第一次校验 singleton 是否为空是为了提高代码执行效率。单例模式只创建一次后面调用就不用加锁直接返回已创建的实例。第二次校验 singleton 是否为空是防止二次创建实例。线程 A 、线程 B 同时进入第一个判断之后线程 B 拿到锁创建了实例然后线程 A 拿到锁之后如果不加以判断就会再次创建实例。singleton 用 volatile 修饰是为了防止 JVM 指令重排序。singleton new Singleton() 分为以下 3 步步骤 3 可能在步骤 2 之前执行此时另外的线程发现 singleton 不为 null直接跳过第一个判断返回未初始化完全的对象就会出问题。分配内存空间初始化对象内存空间赋值给对应的引用静态内部类public class Singleton {private Singleton (){}private static class SingletonHolder {private static final Singleton INSTANCE new Singleton();}public static final Singleton getSingleton(){return SingletonHolder.INSTANCE;}}满足延迟加载Singleton 类被装载了instance 不一定被初始化只有通过显式调用 getInstance 方法时才会显式装载 SingletonHolder 类。对于类的初始化虚拟机规范则严格规定了有且只有四种情况必须立即对类进行初始化遇到 new、getStatic、putStatic 或 invokeStatic 这 4 条字节码指令时如果类没有进行过初始化则需要先触发其初始化。生成这4条指令最常见的 java 代码场景是1)使用 new 关键字实例化对象2)读取一个类的静态字段(被final修饰、已在编译期把结果放在常量池的静态字段除外)3)设置一个类的静态字段(被final修饰、已在编译期把结果放在常量池的静态字段除外)4)调用一个类的静态方法执行类的初始化期间JVM 会获取一个锁同步多个线程对同一个类的初始化所以可以保证线程安全这种方式只适用于静态域的情况静态内部类只能访问外部类的静态成员变量。枚举public enum Singleton {INSTANCE;public void doSomeThing() {}}参考双重检查锁定与延迟初始化-InfoQwww.infoq.cn面试官所认为的单例模式 - 掘金juejin.im