单例模式
多个线程操作不同实例对象。多个线程要操作同一对象,要保证对象的唯一性
单例模式的特点
- 有一个实例化的过程(只有一次),产生实例化对象
- 提供返回实例对象的方法
单例模式的分类
饿汉式
1 | public class HungrySingleton { |
- 线程安全性:在加载的时候已经被实例化,所以只有这一次,线程安全的。
- 懒加载:没有延迟加载
- 性能:长时间不使用,数据一直放在堆中影响性能
懒汉式
1 | public class LazySingleton { |
- 线程安全性:不能保证实例对象的唯一性
- 懒加载:有延迟加载
- 性能:使用时才进行加载,性能较好
懒汉式+同步方法
将懒汉式的get方法加上synchronized
1 | public synchronized static LazySingleton getInstance() { |
- 线程安全性:synchronized保证线程安全
- 懒加载:有延迟加载
- 性能:多个线程调用该方法时 synchronized 会使线程阻塞,退化到了串行执行
Double-Check-Locking
1 | public class DCLSingleton { |
- 线程安全性:线程安全
- 懒加载:有延迟加载
- 性能:性能比较好
- 缺点:会因为指令重排,引起空指针异常。
Volatile+Double-check
添加volatile 避免空指针异常。
1 | private volatile static DCLSingleton instance = null; |
Holder
声明类的时候,成员变量中不声明实例变量,而放到内部静态类中,
1 | public class HolderSingleton { |
枚举
1 | public class EnumSingleton { |

