设计模式:单例模式
来源:互联网 发布:mac访客模式 编辑:程序博客网 时间:2024/06/04 19:57
简单来说,单例模式指在应用的整个生命周期中,只存在一个实例对象。由此可知,单例模式可用于那些整个应用中只存在一个对象的场景,如配置文件、线程池、缓存、例子对象、工具类等。如果创造出多个对象,会出现很多问题,如占用过多资源、不一致的结果等。
UML类图
根据是否lazy初始化,可将单例模式分为“饿汉”和“懒汉”式实现。
“饿汉”式实现
“饿汉”式实现 会在整个应用启动初始化时,就会创建一个实例对象。“饿汉”式实现 是线程安全的,但是由于在应用启动时创建,所以会使得应用启动时间变长。
常规实现
public class Singleton { // 静态变量,声明并初始化 private static Singleton instance = new Singleton(); // 私有化构造方法 private Singleton() { } // 对外提供示例获取的静态方法 public static Singleton getInstance() { return instance; }}
实现简单,线程安全。
枚举实现
public enum Singleton { INSTANCE; public void method_name() { } ...}
这种方式是绝对线程安全的,并支持自动序列化机制。
“懒汉”式实现
“懒汉”式实现 在应用启动时不会立即创建一个实例对象,是在首次被请求调用获取实例对象的方法时才创建对应的实例对象,所以应用启动过程相对“饿汉”式实现会快一点。
简单实现
public class Singleton { // 静态变量,仅声明 private static Singleton instance; // 私有化构造方法 private Singleton() { } // 对外提供示例获取的静态方法 public static Singleton getInstance() { if(instance == null) { instance = new Singleton(); } return instance; }}
多线程环境下,非线程安全。
常规实现
public class Singleton { // 静态变量,仅声明 private static Singleton instance; // 私有化构造方法 private Singleton() { } // 对外提供示例获取的静态方法,使用Synchronized加锁 public static Synchronized Singleton getInstance() { if(instance == null) { instance = new Singleton(); } return instance; }}
多线程情况下,线程安全,但加锁 synchronized影响效率。
双重锁实现
双检锁/双重校验锁(DCL,即 double-checked locking),实现示例如下:
public class Singleton { // 静态变量,仅声明;volatile保证及时可见性 private volatile static Singleton instance; // 私有化构造方法 private Singleton() { } // 对外提供示例获取的静态方法 public static Singleton getInstance() { if(instance == null) { // 检测到未创建时,才加锁保证创建过程是互斥和同步的 Synchronized(Singleton.class) { if(instance == null) { instance = new Singleton(); } } } return instance; }}
线程安全;双重锁校验,可保证多线程下的高性能。
静态内部类实现
public class Singleton { private static class SingletonHolder { private static final Singleton INSTANCE = new Singleton(); } // 私有化构造方法 private Singleton() { } public static Singleton getInstance() { return SingletonHolder.INSTANCE; }}
线程安全;这种实现使用了classloader机制,达到的效果和双重锁实现差不多。
总结
一般情况下,不建议使用 简单实现 和 常规实现 方式,建议使用“饿汉”式实现。只有在要明确实现 lazy loading 效果时,使用静态内部类的方式更佳。如果涉及到反序列化创建对象时,可以尝试使用枚举实现方式。如果有其他特殊的需求,可以考虑使用双重锁校验方式。
阅读全文
1 0
- 设计模式------单例模式
- 设计模式------单例模式
- 设计模式-单例模式
- 设计模式 - 单例模式
- 设计模式---单例模式
- 设计模式---单例模式
- 【设计模式】单例模式
- 设计模式-单例模式
- 设计模式----单例模式
- 设计模式--单例模式
- 设计模式-单例模式
- 设计模式-单例模式
- [设计模式] 单例模式
- 设计模式--单例模式
- 设计模式---单例模式
- 设计模式--单例模式
- 设计模式 -----单例模式
- 设计模式:单例模式
- HDU-2001(两点距离问题)
- win7 python3.6安装教程及环境配置
- Mybatis入门级教程(一)
- 项目管理中的成本计算
- 一中OJ #1086 最大子矩阵 | 贪心连续子序列 + 平面降维压缩 | 解题报告
- 设计模式:单例模式
- 可控定时任务 框架设计实现
- Android Binder通信
- servlet jsp 输出 json 前端js无法解析
- Centos6.5升级内核,并安装docker
- 操作系统:进程同步(2)信号量机制
- HDU-2002(计算球体积)
- Hello CSDN!!!
- springboot跨域请求,实现跨域jsonp请求服务端数据自动封装