iis服务器助手广告广告
返回顶部
首页 > 资讯 > 精选 >JDK双重检查锁定失败怎么解决
  • 416
分享到

JDK双重检查锁定失败怎么解决

2023-06-17 13:06:43 416人浏览 独家记忆
摘要

这篇文章主要介绍了jdk双重检查锁定失败怎么解决的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇JDK双重检查锁定失败怎么解决文章都会有所收获,下面我们一起来看看吧。双重检查锁定在延迟初始化的单例模式中见得比较多

这篇文章主要介绍了jdk双重检查定失败怎么解决的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇JDK双重检查锁定失败怎么解决文章都会有所收获,下面我们一起来看看吧。

双重检查锁定在延迟初始化的单例模式中见得比较多(单例模式实现方式很多,这里为说明双重检查锁定问题,只选取这一种方式),先来看一个版本:

public class Singleton {       private static Singleton instance = null;       private Singleton(){}              public static Singleton  getInstance() {          if(instance == null) {              instance = new Singleton();          }          return instance;       }   }

上面是最原始的模式,一眼就可以看出,在多线程环境下,可能会产生多个Singleton实例,于是有了其同步的版本:

public class Singleton {       private static Singleton instance = null;       private Singleton(){}              public synchronized static Singleton getInstance() {          if(instance == null) {              instance = new Singleton();          }          return instance;       }   }

在这个版本中,每次调用getInstance都需要取得Singleton.class上的锁,然而该锁只是在开始构建Singleton 对象的时候才是必要的,后续的多线程访问,效率会降低,于是有了接下来的版本:

public class Singleton {       private static Singleton instance = null;       private Singleton(){}              public static Singleton getInstance() {          if(instance == null) {              synchronized(Singleton.class) {                 if(instance == null) {                     instance = new Singleton();                 }              }          }          return instance;       }   }

很好的想法!不幸的是,该方案也未能解决问题之根本:

原因在于:初始化Singleton 和 将对象地址写到instance字段 的顺序是不确定的。在某个线程new Singleton()时,在构造方法被调用之前,就为该对象分配了内存空间并将对象的字段设置为默认值。此时就可以将分配的内存地址赋值给instance字段了,然而该对象可能还没有初始化;此时若另外一个线程来调用getInstance,取到的就是状态不正确的对象。

鉴于以上原因,有人可能提出下列解决方案:

public class Singleton {       private static Singleton instance = null;       private Singleton(){}              public static Singleton getInstance() {          if(instance == null) {              Singleton temp;              synchronized(Singleton.class) {                 temp = instance;                 if(temp == null) {                     synchronized(Singleton.class) {                        temp = new Singleton();                     }                     instance = temp;                 }              }          }          return instance;       }   }

该方案将Singleton对象的构造置于最里面的同步块,这种思想是在退出该同步块时设置一个内存屏障,以阻止初始化Singleton 和 将对象地址写到instance字段 的重新排序

不幸的是,这种想法也是错误的,同步的规则不是这样的。退出监视器(退出同步)的规则是:所以在退出监视器前面的动作都必须在释放监视器之前完成。然而,并没有规定说退出监视器之后的动作不能放到退出监视器之前完成。也就是说同步块里的代码必须在退出同步时完成,而同步块后面的代码则可以被编译器或运行时环境移到同步块中执行。

编译器可以合法的,也是合理的,将instance = temp移动到最里层的同步块内,这样就出现了上个版本同样的问题。

在JDK1.5及其后续版本中,扩充了volatile语义,系统将不允许对 写入一个volatile变量的操作与其之前的任何读写操作 重新排序,也不允许将 读取一个volatile变量的操作与其之后的任何读写操作 重新排序。

在jdk1.5及其后的版本中,可以将instance 设置成volatile以让双重检查锁定生效,如下:

public class Singleton {       private static volatile Singleton instance = null;       private Singleton(){}              public static Singleton getInstance() {          if(instance == null) {              synchronized(Singleton.class) {                 if(instance == null) {                     instance = new Singleton();                 }              }          }          return instance;       }   }

需要注意的是:在JDK1.4以及之前的版本中,该方式仍然有问题。

关于“JDK双重检查锁定失败怎么解决”这篇文章的内容就介绍到这里,感谢各位的阅读!相信大家对“JDK双重检查锁定失败怎么解决”知识都有一定的了解,大家如果还想学习更多知识,欢迎关注编程网精选频道。

--结束END--

本文标题: JDK双重检查锁定失败怎么解决

本文链接: https://www.lsjlt.com/news/289332.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • JDK双重检查锁定失败怎么解决
    这篇文章主要介绍了JDK双重检查锁定失败怎么解决的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇JDK双重检查锁定失败怎么解决文章都会有所收获,下面我们一起来看看吧。双重检查锁定在延迟初始化的单例模式中见得比较多...
    99+
    2023-06-17
  • C++11中的双重检查锁定是什么意思
    本篇内容介绍了“C++11中的双重检查锁定是什么意思”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!什么是双重检查锁定?如果你想在多线程编程中...
    99+
    2023-06-17
  • 双重检查锁定模式Java中的陷阱案例
    目录1、简介2、Java中的双重检查锁定3、列举方案3.1 利用 ThreadLocal3.2 利用volatile(解决重排序问题)4、总结1、简介 双重检查锁定(也叫做双重检查锁...
    99+
    2024-04-02
  • PostgreSQL用户登录失败自动锁定怎么解决
    小编给大家分享一下PostgreSQL用户登录失败自动锁定怎么解决,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!一、插件session_exec安装配置篇下载插件...
    99+
    2023-06-14
  • DNS服务器检测失败怎么解决
    如果DNS服务器检测失败,可以尝试以下解决方法:1. 检查网络连接:确保计算机与网络连接正常。可以尝试重新启动计算机、调整网络连接或...
    99+
    2023-08-14
    DNS服务器 服务器
  • Win8提示网络连接失败,请检查网络怎么解决
    要解决Win8提示网络连接失败的问题,可以尝试以下几个步骤:1. 检查网络连接:确保网络电缆或Wi-Fi连接正常。可以尝试重新连接或...
    99+
    2023-10-20
    Win8
  • ubuntu中重启mysql失败怎么解决
    这篇文章主要介绍“ubuntu中重启mysql失败怎么解决”,在日常操作中,相信很多人在ubuntu中重启mysql失败怎么解决问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”...
    99+
    2022-11-30
    ubuntu mysql
  • mongodb重启服务失败怎么解决
    1. 检查 MongoDB 日志文件,查看具体的错误信息,定位问题所在。2. 确认 MongoDB 服务是否已经停止,如果没有停止,...
    99+
    2023-05-24
    mongodb重启服务 mongodb
  • sql目录查找失败怎么解决
    如果在 SQL 中查找目录失败,可能有以下几种原因和解决方法: 语法错误:请确保 SQL 查询语句中的目录路径和表名是正确的,并...
    99+
    2023-10-24
    sql
  • 电脑重装系统失败怎么解决
    这篇文章主要介绍“电脑重装系统失败怎么解决”,在日常操作中,相信很多人在电脑重装系统失败怎么解决问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”电脑重装系统失败怎么解决”的疑惑有所帮助!接下来,请跟着小编一起来...
    99+
    2023-07-01
  • win10重置初始化失败怎么解决
    本篇内容介绍了“win10重置初始化失败怎么解决”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!win10重置初始化失败的解决办法:方法一: ...
    99+
    2023-07-01
  • 阿里云服务器心跳检查失败:如何解决?
    简介 阿里云服务器是一种高性能、高可靠性的云计算服务,但有时候可能会遇到心跳检查失败的问题。本文将介绍心跳检查失败的原因以及解决方法,帮助您快速恢复服务器正常运行。1. 心跳检查失败的原因心跳检查是阿里云服务器的一项重要功能,用于检测服务器...
    99+
    2024-01-31
    阿里 如何解决 服务器
  • u盘重装xp系统失败怎么解决
    这篇文章将为大家详细讲解有关u盘重装xp系统失败怎么解决,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。今天小编收到一位的网友的求救,他使用U盘重装xp系统的时候失败了。要如何解决u盘重装xp...
    99+
    2023-06-28
  • linux重启网络服务失败怎么解决
    如果在Linux系统中重启网络服务失败,可以尝试以下解决方法: 检查网络接口配置:使用命令 ifconfig 或者 ip add...
    99+
    2024-02-29
    linux
  • linux网卡服务重启失败怎么解决
    当Linux网卡服务重启失败时,可以尝试以下解决方法:1. 检查网络配置文件:确认网络配置文件是否存在错误。可以使用命令 `ls /etc/sysconfig/network-scripts/` 来查看网络配置文件列表,并检查每个文件中...
    99+
    2023-08-11
    linux
  • 电脑重置初始化失败怎么解决
    如果电脑重置初始化失败,可以尝试以下方法解决:1. 重新启动电脑:有时候重启电脑可以解决一些临时问题。2. 使用安全模式重置初始化:...
    99+
    2023-10-10
    电脑
  • Tomcat启动失败:严重 [main] org.apache.catalina.util怎么解决
    本文小编为大家详细介绍“Tomcat启动失败:严重 [main] org.apache.catalina.util怎么解决”,内容详细,步骤清晰,细节处理妥当,希望这篇“Tomcat启动失败:严重 [main]...
    99+
    2023-07-05
  • 服务器代理查找失败怎么解决
    服务器代理查找失败可能有多种原因,以下是一些解决方法:1. 检查代理设置:确保代理服务器的IP地址和端口号正确,不要拼写错误或者混淆...
    99+
    2023-06-13
    服务器代理 服务器
  • windows驱动人生查询失败怎么解决
    这篇文章主要介绍“windows驱动人生查询失败怎么解决”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“windows驱动人生查询失败怎么解决”文章能帮助大家解决问题。解决方法:右击桌面右下角网络图标...
    99+
    2023-07-01
  • java重定向后session丢失怎么解决
    当使用重定向后,会新建一个请求,而会话(session)是与请求绑定的,所以在重定向后会丢失会话。解决该问题有以下几种方法:1. 使...
    99+
    2023-10-10
    java session
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作