Singleton Pattern

[TOC]

单例模式

介绍

引用百度百科:

单例模式,属于创建类型的一种常用的软件设计模式。通过单例模式的方法创建的类在当前进程中只有一个实例(根据需要,也有可能一个线程中属于单例,如:仅线程上下文内使用同一个实例)

追求的目标

  • 线程安全

  • 懒加载

  • 调用效率高

方式

饿汉

public class Singleton {

    private static Singleton instance = new Singleton();
 
    private Singleton() {}
 
    public static Singleton getInstance() {
        return instance;
    }
}

懒汉

双重检测

为什么要加volatile?

因为singleton = new Singleton();无法保证原子性,为什么?通常Java文件将使用javac命令编译,得到Class,我们在使用javap -c Singleton.class,将获得Jvm指令,如下:

熟知Synchronized原理的,很快便知道以下指令和代码是对应的:

不熟悉的也没事,我教你呀,飞机票:Synchronized

由此可见,singleton = new Singleton();可以为分为三步:1、创建对象,分配内存;2、实例初始化;3、变量引用实例。

同时,Jvm存在指令重排序情况,那么编译器可能做以下重排序:1、创建对象,分配内存;3、变量引用实例;2、实例初始化;那么在一个实例还没初始化结束的时候,此时已经被变量引用了,那么变量访问实例将会出问题。所以此处必须加上Volatile,因为Volatile的一个重要功能,就是告诉编译器禁止指令重排序。

Volatile原理不明白?没关系,飞机票:Volatile

静态内部类

枚举

对比

方式
优点
缺点

饿汉

线程安全、效率高

非懒加载

懒汉

线程安全、懒加载

效率低

双重检测

线程安全、懒加载、效率高

静态内部类

线程安全、懒加载、效率高

枚举

线程安全、效率高

非懒加载

所以推荐双重检测、静态内部类的写法,实际生产中,更推荐静态内部类的写法,因为便于书写逻辑不易犯错。

Last updated