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 类型是线程安全的。
- 避免反序列化破坏单例 
 
 











 
    
评论