JMM 应用实例:单例模式
单例模式的 8 种写法(这里仅给出 4 种):
饿汉式
双重检查
静态内部类
枚举
什么是单例模式?
所谓类的单例设计模式,就是采取一定的方法保证在整个的软件系统中,对某个类只能存在一个对象实例,并且该类只提供一个取得其对象实例的方法(静态方法)。
单例模式适用的场景
无状态的工具类:
比如日志工具类,不管是在哪里使用,我们需要的只是它帮我们记录日志信息,除此之外,并不需要在它的实例对象上存储任何状态,这时候我们就只需要一个实例对象即可。
全局信息类:
比如我们在一个类上记录网站的访问次数,我们不希望有的访问被记录在对象 A 上,有的却记录在对象 B 上,这时候我们就让这个类成为单例。
饿汉式
双重检查
优点:线程安全;延迟加载;效率高
为什么要使用 double-check?
线程安全
单 check 可不可以?
单 check 也是可以的,但是要考虑到性能问题
为什么要使用 volatile
我们要了解,对象的创建并不是原子性的,对象的创建需要 3 个步骤:
新建一个空的对象
调用构造方法
返回对象
因为创建对象不是原子的,那么就有可能发生步骤 3 发生在步骤 2 之前,就会出现空指针的异常(属性引用时为空,但事实上它需要被赋值)。这恰恰是因为发生了重排序导致的。而使用 volatile 就避免了重排序的发生。
静态内部类
枚举
写法简单
线程安全有保障
通过反编译后代码我们可以看到,public final class T extends Enum
,说明,该类是继承了 Enum 类的,同时 final 关键字告诉我们,这个类也是不能被继承的。同时类中的属性和方法都是 static 的。我们知道当一个 Java 类第一次被真正使用到的时候静态资源被初始化、Java 类的加载和初始化过程都是线程安全的。所以,创建一个 enum 类型是线程安全的。
避免反序列化破坏单例
评论