在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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/363297.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【转】解析.Net框架下的XML编程技术

【引自突破思维的禁忌的博客】一、前言 XML是微软.Net战略的一个重要组成部分,而且它可谓是XML Web服务的基石,所以掌握.Net框架下的XML技术自然显得非常重要了。本文将指导大家如何运用C#语言完成.Net框架下的XML文档的读写操作。首先,我会向…

line-height 属性

p.small {line-height:90%} p.big {line-height:200%} 该属性会影响行框的布局。在应用到一个块级元素时,它定义了该元素中基线之间的最小距离而不是最大距离。 line-height 与 font-size 的计算值之差(在 CSS 中成为“行间距”)分为两半&…

wstngfw中使用Viscosity连接OpenV-P-N服务器

wstngfw中使用Viscosity连接OpenV-P-N服务器 在本例中,将假设以下设置: 站点 A站点 B名称Beijing Office(北京办公室)名称Shenzheng Office(深圳办公室)WAN IP192.168.10.46WAN IP192.168.20.46LAN 子网192…

软件开发薪资调查

软件开发薪资调查 以下是根据朋友和自己面试过的几家公司的了解得到的结果,可能与实际数据有些出入,只做参考。 2~3年工作经验的:杭州 公司名 公司性质 待遇 灵川 欧美(英国…

使用jXLS将Excel文件解析为JavaBeans

这篇文章展示了如何使用jXLS将Excel文件解析为JavaBeans列表。 这是我编写的通用实用程序方法&#xff1a; /** * Parses an excel file into a list of beans. * * param <T> the type of the bean * param xlsFile the excel data file to parse * param jxlsConfigF…

开张了!

今天开张了&#xff0c;试试看&#xff01; Code1using System; 2using System.Collections.Generic; 3using System.Text; 4 5namespace Model 6{ 7 public enum SiteType 8 { System,External,All}; 9 [Serializable]10 class SiteInfo11 {12 public i…

实时监听input输入框value的变化:

HTML5 标准事件 oninput 和 IE 专属事件 onpropertychange 事件实时监听输入框value的变化 oninput 事件在用户输入时触发。 该事件在 <input> 或 <textarea> 元素的值发生改变时触发。 提示&#xff1a; 该事件类似于 onchange 事件。不同之处在于 oninput 事件…

dubbo和zookeeper的关系

转载前言&#xff1a;网络上很多教程没有描述zookeeper和dubbo到底是什么关系、分别扮演了什么角色等信息&#xff0c;都是说一些似是而非的话&#xff0c;这里终于找到一篇文章&#xff0c;比较生动地描述了注册中心和微服务框架之间的关系&#xff0c;以及他们之间的合作分工…

测试Hibernate的最低配置

介绍 在上一篇文章中&#xff0c;我宣布了我打算创建个人Hibernate课程的意图。 首先要做的是最小的测试配置。 这些示例与Hibernate 4有关。 您只需要休眠 在实际的生产环境中&#xff0c;您不会单独使用Hibernate&#xff0c;因为您可以将其集成到JEE或Spring容器中。 要测试…

批处理:修改COM端口号

发现万能的WMI居然没有实现修改COM端口号的方法&#xff0c;不过用来遍历端口信息还是可以的&#xff0c;参考http://msdn.microsoft.com/en-us/library/aa394413(vvs.85).aspx。 没有办法只能通过修改注册表的方式来实现&#xff0c;下面献上代码&#xff0c;自己看吧&#xf…

真是无语

今天是我们有个女同事为了在我们的网站上传一个图片&#xff0c;她从昨天一直传到今天&#xff0c;这张图片都没有传上去。她给一个技术员说了&#xff0c;别人对她说可能是你电脑的问题&#xff0c;还可能是你IE有问题&#xff0c;因为技术员上传一张图片能传上去&#xff0c;…

2.2 .this的绑定规则

2.this的绑定规则 1.默认绑定 1 function foo( )2 {3 console.log(this.a);4 }5 var a1;6 foo(); //1 在代码中&#xff0c;foo()函数不带任何修饰的引用进行调用的&#xff0c;那么只能使用默认绑定。 2.隐式绑定 1 function foo1()2 {3 console.log( this.a );4…

Flink学习(二)Flink中的时间

摘自Apache Flink官网 最早的streaming 架构是storm的lambda架构 分为三个layer batch layerserving layerspeed layer一、在streaming中Flink支持的通知时间 Flink官网写了个了解streaming和各种时间的博客 https://www.oreilly.com/ideas/the-world-beyond-batch-streaming-1…

RSS阅读器使用:ROME,Spring MVC,嵌入式Jetty

在这篇文章中&#xff0c;我将展示一些创建Spring Web应用程序的准则&#xff0c;使用Jetty以及使用名为ROME的外部库运行RSS来运行它。 一般 我最近创建了一个示例Web应用程序&#xff0c;充当RSS阅读器。 我想检查ROME以阅读RSS。 我还想使用Spring容器和MVC创建最简单的视图…

HZOJ string

正解炸了…… 考试的时候想到了正解&#xff0c;非常高兴的打出来了线段树&#xff0c;又调了好长时间&#xff0c;对拍了一下发现除了非常大的点跑的有点慢外其他还行。因为复杂度算着有点高…… 最后正解死于常数太大……旁边的lyl用同样的算法拿了90分我却拿了个暴力的分40……

Unity3D入门其实很简单

在上次发布拙作后&#xff0c;有不少童鞋询问本人如何学习Unity3D。本人自知作为一名刚入门的菜鸟&#xff0c;实在没有资格谈论这么高大上的话题&#xff0c;生怕误导了各位。不过思来想去&#xff0c;决定还是写一些自己的经验&#xff0c;如果能给想要入门U3D的您一些启发&a…

4. HTML表单标签

表单是网页中最常见的元素&#xff0c;也是用户和我们交互的重要手段&#xff0c;在网站中的登录、注册、信息更新这些功能都是依赖表单实现的。在HTML中对于表单提供了一系列的标签&#xff0c;即输入框、下拉框、按钮、文本域&#xff0c;如下是一个最常见的表单结构内容&…

Java 8默认方法可能会破坏您的(用户)代码

乍一看&#xff0c; 默认方法为Java虚拟机的指令集带来了一个很棒的新功能。 最后&#xff0c;库开发人员能够开发已建立的API&#xff0c;而不会对其用户代码造成不兼容性。 使用默认方法&#xff0c;当将新方法引入该接口时&#xff0c;任何实现库接口的用户类都会自动采用默…

ADO.NET之使用DataSet类更新数据库

1.首先从数据库获得数据填充到DataSet类&#xff0c;该类中的表和数据库中的表相互映射。 2.对DataSet类中的表进行修改&#xff08;插入&#xff0c;更新&#xff0c;删除等&#xff09; 3.同步到数据库中&#xff1a;使用SqlDataAdapter实例名.Update(DataSet实例名&#xff…

CSS完美兼容IE6/IE7/FF的通用方法

关于CSS对各个浏览器兼容已经是老生常谈的问题了, 网络上的教程遍地都是.以下内容没有太多新颖, 希望能对初学者有一定的帮助.一、CSS HACK 以下两种方法几乎能解决现今所有HACK. 1, !important 随着IE7对!important的支持, !important 方法现在只针对IE6的HACK.(注意写法.记得…