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

singleton 类

singleton 类_在Java中对Singleton类进行双重检查锁定相关推荐

  1. java中随机数怎么定义类_浅析Java中的随机数类

    Java中的随机数是否可以重复?Java中产生的随机数能否可以用来产生数据库主键?带着这个问题,我们做了一系列测试. 1.测试一: 使用不带参数的Random()构造函数 * @author Carl ...

  2. java group类_浅析Java中线程组(ThreadGroup类)

    Java中使用ThreadGroup类来代表线程组,表示一组线程的集合,可以对一批线程和线程组进行管理.可以把线程归属到某一个线程组中,线程组中可以有线程对象,也可以有线程组,组中还可以有线程,这样的 ...

  3. java calendar 下个月_使用Java中的Calendar类增加一个月

    为Java中的Calendar类导入以下包import java.util.Calendar; 首先,创建一个Calendar对象并显示当前日期Calendar calendar = Calendar ...

  4. java final 类_在Java中,final修饰的类有什么特点

    展开全部 关于Java中的32313133353236313431303231363533e4b893e5b19e31333264663736final(2010-09-09 14:19:48)转载▼ ...

  5. java中的path类_详谈java中File类getPath()、getAbsolutePath()、getCanonical的区别

    简单看一下描述,例子最重要. 1.getPath(): 返回定义时的路径,(就是你写什么路径,他就返回什么路径) 2.getAbsolutePath(): 返回绝对路径,但不会处理".&qu ...

  6. python中的元类_理解python中的元类

    一,理解类也是对象 在python中类同样也是一种对象,只要使用关键字class,Python解释器在执行的时候就会创建一个对象,这个对象(类)自身拥有创建对象(类实例)的能力,这就是为什么他是一个类 ...

  7. java订单类_基于Java创建一个订单类代码实例

    这篇文章主要介绍了基于Java创建一个订单类代码实例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 需求描述 定义一个类,描述订单信息 订单id 订 ...

  8. java订单类_使用Java创建一个订单类代码实例

    这篇文章主要简介了使用Java创建一个订单类代码实例,文中通过示例代码简介的非常具体,对大家的学习或者工作具有一定的参考学习网上卖,需要的朋友可以学习下 需求描述 定义一个类,描述订单信息 订单id ...

  9. java设计一个user类_关于JAVA设计一个用户类

    关于JAVA设计一个用户类 关注:152  答案:2  mip版 解决时间 2021-02-02 05:51 提问者安分守己的小青春 2021-02-02 02:23 设计一个用户类,该类有用户编号. ...

最新文章

  1. zippo油和zorro油的区别_干式和油侵式变压器的概念和区别
  2. 80端口被占用pid 4,svhost等占用的解决方法
  3. CTFshow 文件包含 web117
  4. ios view 切上部分圆角_ios – 具有圆角的UIView:如何正确剪辑子视图?
  5. .Android项目导入时,出现的Could not write file 。。。。。。.classpath错误解决办法
  6. SaltStack部署
  7. javascript小游戏_个人网站集成js小游戏《圈小猫》教程及源码
  8. python爬取bilibili弹幕_GitHub - yxwangnju/Bilibili-Bullet-Screen-Crawler: 一个爬取bilibili上弹幕的简单python程序...
  9. Spread for Windows Forms高级主题(4)---自定义用户交互
  10. 数据结构中的头结点和头指针
  11. catia圆角交点如何标注_标签软件如何制作口罩合格证
  12. 足球运动员要加强保护设备
  13. 字符串通配符(动态规划)
  14. editplus使用php,EditPlus配置PHP调试环境详细图文介绍
  15. 《SEM长尾搜索营销策略解密》一一2.3 一个长尾周期倒下来,还有千千万万个站起来...
  16. 开始时间 结束时间,全程的运行时间的计算
  17. sumif单列求和_求和、单条件求和、多条件求和、隔列求和等实用技巧解读
  18. 六轴UR机械臂正逆运动学求解_MATLAB代码(标准DH参数表)
  19. unity游戏,隐私协议最简单解决方案!仅3行代码就搞定!
  20. MySql 笔记(五)InnoDB引擎页分裂与页合并的原理

热门文章

  1. POJ1151-Atlantis【线段树,扫描线,离散化】
  2. POJ2018-Best Cow Fences【实数二分答案】
  3. 【2018.3.24】模拟赛之五-ssl1864 得分【dp,贪心】
  4. JavaFX UI控件教程(九)之Text Field
  5. Oracle入门(十二A)之数据类型
  6. 班级日常分享 | 一天一瞬间!
  7. 使用java将字符串写入到指定的文件中
  8. 三个水桶(看了三遍,想了五遍!)
  9. SQL分组取每组前一(或几)条记录(排名)
  10. spring(10)通过spring 和 JDBC征服数据库