一、定义
单例模式是创建型的
定义:确保一个类只有一个实例,并提供该实例的全局访问点
组成:使用了一个私有构造函数、一个私有静态变量以及一个公有静态函数来实现。
私有构造函数保证玩了不能通过构造函数来创建对象实例,只能通过公有静态函数返回唯一的私有静态变量。
二、实现
1、饿汉式
应用场景:
1、初始化时就需创建单例
2、单例对象要求初始化速度快,占用内存小
原理:
依赖JVM类加载机制,保证单例只被创建一次
优点:
1、线程安全
2、初始化速度快
3、占用内存小
缺点:
1、创建时机不可控制
javaprivate static Singleton uniqueInstance = new Singleton();
2、枚举类型
应用场景:
1、初始化时就需创建单例
2、单例对象要求初始化速度快,占用内存小
原理:
1、枚举类型 = 不可被继承的类
2、每个枚举元素 = 类静态常量 = 依赖JVM 类加载机制,保证单例只被创建1次
3、枚举元素都通过静态代码块来进行初始化
4、构造方法访问权限 默认 = 私有 (private)
5、大部分方法都是final
优点:
1、线程安全
2、自由序列化
3、实现更加简单、简洁
缺点:
1、创建时间不可控制
javapublic enum Singleton { uniqueInstance; }
3、懒汉式
应用场景:
1、按需、延迟创建单例
2、单例初始化的操作耗时长
3、单例的占用内存比较大
原理:
1、类加载时,先不自动创建单例
2、需要时手动创建单例
优点:
1、按需加载单例
2、节约资源
缺点:
1、线程不安全
javapublic class Singleton { private static Singleton uniqueInstance; private Singleton() { } public static Singleton getUniqueInstance() { if (uniqueInstance == null) { uniqueInstance = new Singleton(); } return uniqueInstance; } }
4、同步锁
应用场景:
1、按需、延迟创建单例
2、单例初始化的操作耗时长
3、单例的占用内存比较大
原理:
1、使用同步锁 synchronized 锁住创建单例的方法
优点:
1、线程安全
缺点:
1、造成过多的同步开销
5、双重校验锁
应用场景:
1、按需、延迟创建单例
2、单例初始化的操作耗时长
3、单例的占用内存比较大
原理:
锁一:若单例已创建,则直接返回已创建的单例,无需再执行加锁操作
锁二:防止多次创建单例问题
优点:
1、线程安全
2、节约资源
缺点:
1、实现复杂
javapublic class Singleton { private volatile static Singleton uniqueInstance; private Singleton() { } public static Singleton getUniqueInstance() { if (uniqueInstance == null) { synchronized (Singleton.class) { if (uniqueInstance == null) { uniqueInstance = new Singleton(); } } } return uniqueInstance; } }
6、静态内部类
应用场景:
1、按需、延迟创建单例
2、单例初始化的操作耗时长
3、单例的占用内存比较大
原理:
1、在静态内部类里创建单例,在装载该内部类时才会去创建单例
2、类是由JVM加载,而JVM只会加载1遍,保证只有一个单例
优点:
1、线程安全
2、节省资源
3、实现简单
javapublic class Singleton { private Singleton() { } private static class SingletonHolder { private static final Singleton INSTANCE = new Singleton(); } public static Singleton getUniqueInstance() { return SingletonHolder.INSTANCE; } }