单例模式的几种实现
来源:互联网 发布:免费叫卖录音软件 编辑:程序博客网 时间:2024/06/07 11:48
单例模式的几种实现
在开发中,我们总是会遇到使用单例模式的情况,今天就来总结一下几种实现单例模式的方法。
1.单例模式(懒汉式)的最佳写法(特别说到这个问题,是因为网上很多这样的代码)。
public class Singleton { private static Singleton singleton; public Singleton() { } public static Singleton getInstance() { if (singleton == null) { singleton = new Singleton(); } return singleton; }}
这种写法只能在单线程下使用。如果是多线程,可能发生一个线程通过并进入了 if (singleton == null) 判断语句块,但还未来得及创建新的实例时,另一个线程也通过了这个判断语句,两个线程最终都进行了创建,导致多个实例的产生。所以在多线程环境下必须摒弃此方式。
这种写法线程不安全。
2.加入同步锁。
public class Singleton { private static Singleton singleton; public Singleton() { } public static synchronized Singleton getInstance() { if (singleton == null) { singleton = new Singleton(); } return singleton; }}
通过为 getInstence() 方法增加 synchronized 关键字,迫使每个线程在进入这个方法前,要先等候别的线程离开该方法,即不会有两个线程可以同时进入此方法执行 new Singleton(),从而保证了单例的有效。但它的致命缺陷是效率太低了,每个线程每次执行 getInstance() 方法获取类的实例时,都会进行同步。而事实上实例创建完成后,同步就变为不必要的开销了,这样做在高并发下必然会拖垮性能。所以此方法虽然可行但也不推荐。
网上这样的代码更多,可以很好的工作,但是缺点是效率低。
3.实际上,早在JDK1.5就引入volatile关键字,所以又有了一种更好的双重校验锁写法。
public class Singleton { private volatile static Singleton singleton; public Singleton() { } public static Singleton getInstance() { if (singleton == null) { synchronized (Singleton.class) { if (singleton == null) { singleton = new Singleton(); } } } return singleton; }}
DCL体现在进行了两次 if (singleton == null) 的检查,这样既同步代码块保证了线程安全,同时实例化的代码也只会执行一次,实例化后同步操作不会再被执行,从而效率提升很多。
双重检查锁定(DCL)方式也是延迟加载的,它唯一的问题是,由于 Java 编译器允许处理器乱序执行,在 JDK 版本小于 1.5 时会有 DCL 失效的问题(原因解释详见附录 2)。当然,现在大家使用的 JDK 普遍都已超过 1.4,只要在定义单例时加上 1.5 及以上版本具体化了的 volatile 关键字,即可保证执行的顺序,从而使单例起效。所以 DCL 方式是推荐的一种方式。
Android 中鼎鼎大名的 Universal Image Loader 和 EventBus 都是采用了这种方式的单例
这才是最佳写法!!!
不是说第二种写法有问题,或者在Android中一定要用第三种写法,只是告诉大家一种更好的写法。
- 单例模式的几种实现
- 单例模式的几种实现
- 单例模式的几种实现
- 单例模式的几种实现
- 单例模式的几种实现
- IOS实现单例模式的几种实现方法
- IOS实现单例模式的几种实现方法
- 单例模式的几种实现方式的对比
- java单例模式的几种实现
- JAVA单例模式的几种实现方法
- 单例模式singleton的几种实现方式
- JAVA单例模式的几种实现方法
- JAVA单例模式的几种实现方法
- 单例模式的几种实现及其比较
- JAVA单例模式的几种实现方法
- JAVA单例模式的几种实现方法
- JAVA单例模式的几种实现方法
- 单例模式(singleton pattern)的几种实现
- mysql免安装版常用操作
- ios学习路线—Objective-C(检查内存泄露方式(Instruments))
- 【框架】as制作sdk
- mongo VUE的使用(增删改查以及创建索引的非常规办法)
- Redis 集群教程
- 单例模式的几种实现
- Java基本数据类型
- hdu 5583 Kingdom of Black and White 思路题
- Remote System Explorer Operation卡死Eclipse解决方案
- logback 入门学习(二)
- Cannot change version of project facet Dynamic web 3.0
- js 更改URL参数
- Java使用imageio 读写图像
- 【muduo库学习】实现最简单的reactor模式