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类进行双重检查锁定相关推荐

  1. singleton 类_在Java中对Singleton类进行双重检查锁定

    singleton 类 Singleton类在Java开发人员中非常常见,但是它给初级开发人员带来了许多挑战. 他们面临的主要挑战之一是如何使Singleton保持为Singleton? 也就是说,无 ...

  2. Java盲点:双重检查锁定及单例模式

    时间:2009-08-11 19:20    来源:未知    作者:Peter Haggar 核心提示:Peter Haggar , 高级软件工程师, IBM 2004 年 5 月 01 日 所有的 ...

  3. java 双重检查锁定及单例模式

    双重检查锁定及单例模式 全面理解这一失效的编程习语 Peter Haggar , 高级软件工程师, IBM Peter Haggar 是 IBM 在北卡罗来纳州的 Research Triangle ...

  4. 双重检查锁定及单例模式

                                         双重检查锁定及单例模式 转载 http://www.ibm.com/developerworks/cn/java/j-dcl. ...

  5. C++11 修复了双重检查锁定问题(转)

    从网上看到了一篇这个文章,收藏一下 导读:本文是关于C++11标准中修复了双重检查锁定模式的消息,同时作者阐述了实现双重检查锁定模式的诸多方法,并逐一进行了分析,作者还提供了一个在早期编译器上实现双重 ...

  6. Java中的双重检查锁定

    在本文中,我们将介绍在RxJava中创建Singleton对象的一些技术. 最重要的是,我们将学习Java中的双重检查锁定 . Java中的Singleton模式是一种创新模式. 随着时间的流逝,人们 ...

  7. java 双重检查锁 失效_关于多线程:为什么Java中双重检查锁定被打破?

    此问题与旧Java版本的行为以及双重检查锁定算法的旧实现有关 较新的实现使用volatile并依赖于稍微改变的volatile语义,因此它们没有损坏. 声明字段分配始终是原子的,除了long或doub ...

  8. java 中常用的类

    java 中常用的类 Math Math 类,包含用于执行基本数学运算的方法 常用API 取整 l  static double abs(double  a) 获取double 的绝对值 l  sta ...

  9. Java中的BigDecimal类你真的了解吗?

    点击上方"方志朋",选择"设为星标" 回复"666"获取新整理的面试资料 作者:HikariCP www.jianshu.com/p/c81 ...

最新文章

  1. ASP.NET页面借助IFrame提交表单数据所遇到的问题
  2. maven上解决循环依赖、又不想新加第三模块的方法
  3. 使用mod_proxy_balancer实现负载均衡
  4. 用PC端Chrome浏览器进行模拟微信浏览器的开发
  5. 如何使用Linux的Crontab定时执行PHP脚本的方法
  6. 信息收集——子域名收集
  7. 工作53:$router问题
  8. c++判断ftp服务器文件存在性判断_BitTorrent协议与传统文件分发协议对比
  9. 图像处理经典文章合集
  10. google开源数学引擎_Google的开源PDF引擎,开放无线运动等
  11. Bootstrap 分页导航的尺寸
  12. camera ---(6)双摄成像原理
  13. Objectove-c单例模式
  14. 币安“碟中谍”,真相只有一个
  15. adb工具箱_安卓福音,史上最强搞机工具箱,一键修手机
  16. 图纸管理软件保证图纸最新版本正确方法
  17. mysql directx repair_[MySQL]快速解决is marked as crashed and should be repaired故障
  18. android ts合并_ts视频合并工具安卓版
  19. pycharm 文件名颜色所代表的含义
  20. python设函数解方程_如何在Python函数最小化中获得速度,求椭球方程解

热门文章

  1. 检查异常和非检查异常 有空你去学一下检查异常和非检查异常
  2. 定时任务重启后执行策略_C语言操作时间函数time.ctime,实现定时执行某个任务小例子...
  3. centos普通用户修改文件权限_用户管理(特殊权限、特殊属性、umask 默认权限 )
  4. 多个会话对表加表级读锁和表级写锁后的操作权限分析(表级读锁+表级写锁)
  5. Spring IOC 如何解决循环依赖?
  6. java orm框架有哪些_Java Stream ORM现在带有JOIN
  7. java项目教训_[免费电子书]分析超过600,000个Java项目的经验教训
  8. java中使用kotlin_在Kotlin中使用libGDX
  9. jooq_jOOQ API设计缺陷的怪异事件
  10. 使用JUnit5对DynamoDB应用程序进行单元测试