首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

JUC并发编程之单例模式双重检验锁陷阱

1 前言 我在上一篇文章聊volatile的时候,埋下了一个问题,在并发情况下单例模式双重检验锁可能会存在的问题,那么本文就来详细分析分析它。...2 浅谈单例模式双重检验锁陷阱 首先看一段代码 public class Test04 { private static Test04 test04; public static Test04...} } //-----输出结果 com.dream.sunny.Test04@3f99bd52 com.dream.sunny.Test04@3f99bd52 true 如上是一段单例模式中的懒汉模式双重检验锁...双重检验锁问题解决方案 回头看下我们出问题的双重检查锁程序,它是满足as-if-serial语义的吗?是的,单线程下它没有任何问题,但是在多线程下,会因为重排序出现问题。...volatile是Java虚拟机提供的轻量级的同步机制。

47930
  • 您找到你想要的搜索结果了吗?
    是的
    没有找到

    并发情况下,单例模式之双重检验锁陷阱

    在我前面有写过一篇关于单例模式的几种创建的文章,最近在看多线程的时候,发现如果使用双重检验锁则可能会发生问题,接下来看我细细道来 单例模式的几种创建方式文章地址:https://www.jianshu.com...singletonV4; private SingletonV4() { System.out.println("--初始化--"); } /** * 双重检验锁...} --初始化-- com.dream.sunny.SingletonV4@1716361 com.dream.sunny.SingletonV4@1716361 如上是一段单例模式中的懒汉模式双重检验锁...双重检验锁问题解决方案 回头看下我们出问题的双重检查锁程序,它是满足as-if-serial语义的吗?是的,单线程下它没有任何问题,但是在多线程下,会因为重排序出现问题。...singletonV4; private SingletonV4() { System.out.println("--初始化--"); } /** * 双重检验

    85522

    【地铁上的设计模式】--创建型模式:单例模式(三)--双重检验锁单例

    什么是双重检验锁单例 双重检验锁单例模式实现了懒汉式单例模式的延迟加载和饿汉式单例模式的线程安全。其主要思路是在获取单例实例时,先检查是否已经实例化,如果没有才进行同步块。...如何实现双重检验锁单例 双重检验锁单例模式的实现步骤如下: 将构造函数设为私有,防止外部直接实例化该类; 声明一个静态的私有变量来保存类的唯一实例; 提供一个公有的静态方法获取类的唯一实例,在方法内部进行双重检验锁...Java实现 public class Singleton { private volatile static Singleton instance; private Singleton...总结 双重检验锁单例模式能够确保只有一个实例被创建,并具有较好的性能表现和延迟创建的能力。其优点是在多线程环境下可以保证线程安全,并且可以延迟对象的创建,节省了系统资源。...缺点是在某些情况下可能会出现线程安全问题,例如在JDK1.4之前的版本中使用双重检验锁时可能会因为指令重排而导致多线程下出现创建多个实例的问题。

    23910

    聊聊设计模式之单例模式(上)

    我们再次分析上述代码,可以发现,其实只有当创建对象的时候才需要加锁,也就是这行代码 singleton=new Singleton(); 需要加锁,其他代码是可以不加锁的,如果我们在创建对象的时候再加锁...,而不是在整个方法上加锁,那么性能自然就提高了。...有同学可能会有疑问,为什么需要做双重检验呢?明明在同步块外面已经对singleton对象是否为空做了判断,为何在同步块内部还需要再判断一次呢?...因此才需要做双重校验以防止singleton对象被实例化多次。 然而,上述“双重检验”仍然是有漏洞的。在某些情况下当singleton不等于null时,可能singleton引用的对象还未完成初始化。...因此上述“双重检验”的实现是有问题的,那么有没有其他办法避免上述问题呢?当然有。笔者将在后续文章为大家详细介绍。

    76260

    Java单例模式中双重检查锁的问题

    在努力创建更有效的代码时,Java 程序员们创建了双重检查锁定习语,将其和单例创建模式一起使用,从而限制同步代码量。...然而,由于一些不太常见的 Java 内存模型细节的原因,并不能保证这个双重检查锁定习语有效。 它偶尔会失败,而不是总失败。此外,它失败的原因并不明显,还包含 Java 内存模型的一些隐秘细节。...双重检查锁定失败的问题并不归咎于 JVM 中的实现 bug,而是归咎于 Java 平台内存模型。内存模型允许所谓的“无序写入”,这也是这些习语失败的一个主要原因。...针对 Java 技术的 IBM SDK 1.3 版和 Sun JDK 1.3 都生成这样的代码。然而,这并不意味着应该在这些实例中使用双重检查锁定。该习语失败还有一些其他原因。...在 developerWorks Java 技术专区 查找其他的 Java 技术资料。

    1.9K20

    JAVA并发之加锁导致的活跃性问题剖析

    首先提及一下前置知识: 1.JAVA并发之基础概念 2.JAVA并发之进程VS线程 3.JAVA并发之多线程引发的问题剖析及如何保证线程安全 在前三章我们讨论了多线程并发的优点以及如何加锁来处理并发带来的安全性问题...这个和简单的加锁超时类似,不一样的是只有死锁已经发生了才回退,而不会是因为加锁的请求超时了。...解决饥饿 Java 不可能实现 100% 的公平性,我们依然可以通过同步结构在线程间实现公平性的提高。...CAS 算法 - Java 的 Atomic 包使用 CAS 算法来更新数据,而不需要加锁。...总结 至本章为止,多线程并发的概念篇就结束了,实际操作篇尽情期待 持续关注公众号 JAVA宝典

    1.1K31

    【死磕Java并发】-----分析 ArrayBlockingQueue 构造函数加锁问题

    原文出处http://cmsblogs.com/ 『chenssy』 昨天有位小伙伴问我一个 ArrayBlockingQueue 中的一个构造函数为何需要加锁,其实这个问题我还真没有注意过。...主要是在看 ArrayBlockingQueue 源码时,觉得它很简单,不就是通过加锁的方式来操作一个数组 items 么,有什么难的,所以就没有关注这个问题,所以它一问我懵逼了。...如果不加锁为什么就没法保证 items 的可见性呢?这其实是指令重排序的问题。 什么是指令重排序?编译器或运行时环境为了优化程序性能而采取的对指令进行重新排序执行的一种手段。...更多请参考博客【死磕Java并发】—–Java内存模型之重排序。 为什么说指令重排序会影响 items 的可见性呢?...推荐阅读: 【死磕Java并发】—–Java内存模型之重排序 【死磕Java并发】—–Java内存模型之从JMM角度分析DCL 【死磕Java并发】—–深入分析volatile的实现原理 【死磕Java

    1.2K60

    JAVA并发之加锁导致的活跃性问题剖析

    在前三章我们讨论了多线程并发的优点以及如何加锁来处理并发带来的安全性问题 但是加锁也为我们带来了诸多问题 如:死锁,活锁,线程饥饿等问题 这一章我我们主要处理锁带来的问题....T2 time out T4 time out T3 time out 2.按顺序加锁 >按照顺序加锁是一种有效防止死锁的机制,但是这种方式,你需要先知道所有可能用到锁的位置,并对这些锁安排一个顺序...这个和简单的加锁超时类似,不一样的是只有死锁已经发生了才回退,而不会是因为加锁的请求超时了。...解决饥饿 Java 不可能实现 100% 的公平性,我们依然可以通过同步结构在线程间实现公平性的提高。...CAS 算法 - Java 的 Atomic 包使用 CAS 算法来更新数据,而不需要加锁

    48220
    领券