在Java中对Singleton类进行双重检查锁定
Singleton类在Java开发人员中非常常见,但是它给初级开发人员带来了许多挑战。 他们面临的主要挑战之一是如何使Singleton保持为Singleton? 也就是说,无论出于何种原因,如何防止单个实例的多个实例。 对Singleton进行双重检查锁定是一种确保在应用程序生命周期中仅创建Singleton类的一个实例的方法。 顾名思义,在双重检查锁定中,代码对一个Singleton类的现有实例进行两次检查(有和没有锁定以进行两次检查),以确保不会创建一个以上的singleton实例。 顺便说一句,它在Java修复JDK 1.5中的内存模型问题之前就被打破了。 在本文中,我们将看到如何在Java中为Singleton的双重检查锁定编写代码 ,为什么在Java 5之前双重检查锁定被破坏以及如何解决。 顺便说一句,从访谈的角度来看,这也很重要,我听说有人要求对金融和服务业的公司进行手工双重检查Singleton锁定的代码,并相信我很棘手,直到您清楚地了解了什么你在做。 您也可以查看我的Singleton设计模式问题的完整列表,以进行良好的准备。
Singleton类破坏其合同的一种常见情况是多线程。 如果您要求初学者为Singleton设计模式编写代码,那么他很有可能会提出以下内容:
private static Singleton _instance;public static Singleton getInstance() {if (_instance == null) {_instance = new Singleton();}return _instance;
}
并且当您指出这段代码将由多个线程并行调用时,将创建Singleton类的多个实例时,他可能会使整个getInstance()方法同步化 ,如第二个代码示例getInstanceTS()方法所示。 尽管它是线程安全的,可以解决多个实例的问题,但效率不是很高。 每次调用此方法时,都需要承担同步的费用,而创建Singleton实例时,仅在第一类上才需要同步。 这将使我们进入双重检查的锁定模式 ,其中只有关键的代码段被锁定。 程序员称其为“双重检查锁定”,因为对_instance == null进行了两次检查,一次没有锁定,而另一次则带有锁定(内部同步)块。 这是Java中经过双重检查的锁定的样子:
public static Singleton getInstanceDC() {if (_instance == null) { // Single Checkedsynchronized (Singleton.class) {if (_instance == null) { // Double checked_instance = new Singleton();}}}return _instance;
}
从表面上看,这种方法看起来很完美,因为您只需要为同步块支付一次费用,但是在使_instance变量volatile之前,它仍然无效。 如果没有volatile修饰符,则Java中的另一个线程可能会看到_instance变量的一半初始化状态,但是由于volatile变量保证了before-before关系的发生,所有写入都会在_instance变量的任何读取之前发生在volatile _instance上。 在Java 5之前不是这种情况,这就是为什么以前双重检查锁定已被破坏的原因。 现在,有了事前保证 ,您可以放心地认为这将起作用。 顺便说一下,这不是创建线程安全的Singleton的最佳方法,您可以将Enum用作Singleton ,它在实例创建期间提供内置的线程安全性。 另一种方法是使用静态持有人模式。
/** A journey to write double checked locking of Singleton class in Java.*/class Singleton {private volatile static Singleton _instance;private Singleton() {// preventing Singleton object instantiation from outside}/** 1st version: creates multiple instance if two thread access* this method simultaneously*/public static Singleton getInstance() {if (_instance == null) {_instance = new Singleton();}return _instance;}/** 2nd version : this definitely thread-safe and only* creates one instance of Singleton on concurrent environment* but unnecessarily expensive due to cost of synchronization* at every call.*/public static synchronized Singleton getInstanceTS() {if (_instance == null) {_instance = new Singleton();}return _instance;}/** 3rd version : An implementation of double checked locking of Singleton.* Intention is to minimize cost of synchronization and improve performance,* by only locking critical section of code, the code which createsinstance of Singleton class.* By the way this is still broken, if we don't make _instance volatile,as another thread can* see a half initialized instance of Singleton.*/public static Singleton getInstanceDC() {if (_instance == null) {synchronized (Singleton.class) {if (_instance == null) {_instance = new Singleton();}}}return _instance;}
}
这就是Java中对Singleton类的双重检查锁定 。 这是在Java中创建线程安全的Singleton的有争议的方法之一,就将Enum用作Singleton类而言,还有其他更简单的选择。 我不建议您像那样实现Singleton,因为有许多更好的方法可以在Java中实现Singleton模式。 但是,这个问题具有历史意义,并且还教导了并发如何引入细微的错误。 正如我之前所说,从访谈的角度来看,这非常重要。 在进行任何Java面试之前,练习手动编写Singleton类的双重检查锁定。 这将使您深入了解Java程序员的编码错误。 与此相关的是,在现代的测试驱动开发中,由于Singleton难以模拟其行为,因此Singleton被视为反模式,因此,如果您是TDD实践者,最好避免使用Singleton模式。
翻译自: https://www.javacodegeeks.com/2014/05/double-checked-locking-on-singleton-class-in-java.html
在Java中对Singleton类进行双重检查锁定相关推荐
- singleton 类_在Java中对Singleton类进行双重检查锁定
singleton 类 Singleton类在Java开发人员中非常常见,但是它给初级开发人员带来了许多挑战. 他们面临的主要挑战之一是如何使Singleton保持为Singleton? 也就是说,无 ...
- Java盲点:双重检查锁定及单例模式
时间:2009-08-11 19:20 来源:未知 作者:Peter Haggar 核心提示:Peter Haggar , 高级软件工程师, IBM 2004 年 5 月 01 日 所有的 ...
- java 双重检查锁定及单例模式
双重检查锁定及单例模式 全面理解这一失效的编程习语 Peter Haggar , 高级软件工程师, IBM Peter Haggar 是 IBM 在北卡罗来纳州的 Research Triangle ...
- 双重检查锁定及单例模式
双重检查锁定及单例模式 转载 http://www.ibm.com/developerworks/cn/java/j-dcl. ...
- C++11 修复了双重检查锁定问题(转)
从网上看到了一篇这个文章,收藏一下 导读:本文是关于C++11标准中修复了双重检查锁定模式的消息,同时作者阐述了实现双重检查锁定模式的诸多方法,并逐一进行了分析,作者还提供了一个在早期编译器上实现双重 ...
- Java中的双重检查锁定
在本文中,我们将介绍在RxJava中创建Singleton对象的一些技术. 最重要的是,我们将学习Java中的双重检查锁定 . Java中的Singleton模式是一种创新模式. 随着时间的流逝,人们 ...
- java 双重检查锁 失效_关于多线程:为什么Java中双重检查锁定被打破?
此问题与旧Java版本的行为以及双重检查锁定算法的旧实现有关 较新的实现使用volatile并依赖于稍微改变的volatile语义,因此它们没有损坏. 声明字段分配始终是原子的,除了long或doub ...
- java 中常用的类
java 中常用的类 Math Math 类,包含用于执行基本数学运算的方法 常用API 取整 l static double abs(double a) 获取double 的绝对值 l sta ...
- Java中的BigDecimal类你真的了解吗?
点击上方"方志朋",选择"设为星标" 回复"666"获取新整理的面试资料 作者:HikariCP www.jianshu.com/p/c81 ...
最新文章
- ASP.NET页面借助IFrame提交表单数据所遇到的问题
- maven上解决循环依赖、又不想新加第三模块的方法
- 使用mod_proxy_balancer实现负载均衡
- 用PC端Chrome浏览器进行模拟微信浏览器的开发
- 如何使用Linux的Crontab定时执行PHP脚本的方法
- 信息收集——子域名收集
- 工作53:$router问题
- c++判断ftp服务器文件存在性判断_BitTorrent协议与传统文件分发协议对比
- 图像处理经典文章合集
- google开源数学引擎_Google的开源PDF引擎,开放无线运动等
- Bootstrap 分页导航的尺寸
- camera ---(6)双摄成像原理
- Objectove-c单例模式
- 币安“碟中谍”,真相只有一个
- adb工具箱_安卓福音,史上最强搞机工具箱,一键修手机
- 图纸管理软件保证图纸最新版本正确方法
- mysql directx repair_[MySQL]快速解决is marked as crashed and should be repaired故障
- android ts合并_ts视频合并工具安卓版
- pycharm 文件名颜色所代表的含义
- python设函数解方程_如何在Python函数最小化中获得速度,求椭球方程解
热门文章
- 检查异常和非检查异常 有空你去学一下检查异常和非检查异常
- 定时任务重启后执行策略_C语言操作时间函数time.ctime,实现定时执行某个任务小例子...
- centos普通用户修改文件权限_用户管理(特殊权限、特殊属性、umask 默认权限 )
- 多个会话对表加表级读锁和表级写锁后的操作权限分析(表级读锁+表级写锁)
- Spring IOC 如何解决循环依赖?
- java orm框架有哪些_Java Stream ORM现在带有JOIN
- java项目教训_[免费电子书]分析超过600,000个Java项目的经验教训
- java中使用kotlin_在Kotlin中使用libGDX
- jooq_jOOQ API设计缺陷的怪异事件
- 使用JUnit5对DynamoDB应用程序进行单元测试