DCL 还坏吗?

2023-12-13

据我了解,旧的 JMM 实现惰性单调的 DCL(双重检查锁定)技巧已被破坏,但我认为新的 JMM 和易失性字段已修复它......

然而在this不错的文章,显然足够新,可以引用新旧 JMM 和 DCL 中的易失性字段,指出它仍然损坏......

我到处读到它已修复,然后我发现了这一点...有人可以说最后它是否损坏了?

我的理解是,通过 volatile 保证关系发生之前的情况并有效地发出 membar 解决问题,并且 DCL 现在有效......尽管我同意静态惰性初始化更可取并且更容易理解......


我到处读到它已修复,然后我发现了这一点...有人可以说最后它是否损坏了?

这取决于你所说的“它”是什么意思。

如果您问是否可以使用 volatile 执行 DCL,那么答案是肯定的,在 Java 5 之后。(原始语义volatile没有明确定义,这意味着使用volatile在 Java 5 之前没有修复。)

如果您询问是否可以在没有 易失性的情况下执行 DCL,那么答案是否定的。Java 5 内存模型更改不会“修复”具有非易失性的 DCL 的原始 Java 实现instance多变的。

如果您问对于延迟初始化的单例使用 DCL 是否仍然是一个好主意,那么答案是否定的。(在我看来):

  • 有更好的方法来实现延迟初始化的单例。使用enum是其中之一。

  • Since the DCL idiom is still error prone and not well understood1, it is better to avoid it.

  • 同步性能的改进很大程度上消除了对 DCL 的需求。


枚举和静态初始化将在类加载时初始化单例(如果我错了,请纠正我)。

我想,那你就错了。类初始化也是惰性的。除非你强制,否则它不会在类加载时发生;例如通过使用3-arg 过载 of Class.forName. JLS 12.4.1规定了确定何时发生的规则。

结果是,您可以确保基于枚举的单例的初始化是延迟发生的,并且肯定会安全地完成。

顺便说一句,延迟初始化的硬性要求对我来说表明您的应用程序设计中存在问题。至少,它引入了一个脆弱点……无论延迟初始化是如何实现的。


1 - If an "average Joe programmer" doesn't understand the intricacies of DCL, then it is a bad idea to use DCL in code that he might need to maintain. The fact that you are smarter than the average Joe programmer is moot.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

DCL 还坏吗? 的相关文章

随机推荐

  • Rails 5 - 保存回滚,因为嵌套模型父模型未在子模型之前保存

    好吧 伙计们 Rails 5 确实与 Rails 4 有细微差别 我遇到的情况是 每次我单击表单上的提交按钮时 它都会重新加载并显示错误配置文件用户必须存在 and 个人资料用户不能为空 该表单加载良好 包括嵌套模型表单 但由于某种原因 在
  • java.lang.NumberFormatException:对于输入字符串:“22”

    public void loadFromFile String filename File file new File filename BufferedReader br try br new BufferedReader new Fil
  • ArrayList:大小如何增加?

    我有一个关于Java的基本问题ArrayList When ArrayList使用默认构造函数声明并初始化 创建 10 个元素的内存空间 现在 当我添加第 11 个元素时 会发生什么 是否会创建具有 20 个 或更多 元素容量的新内存空间
  • C 函数指针

    static void increment long long n n struct test void work fn long long struct test t1 t1 work fn increment 我现在如何实际调用该函数
  • Spring boot mongodb审计错误

    我正在尝试在 Spring Boot 应用程序中配置 mongodb 审核 并且在尝试保留域类时遇到此错误 java lang IllegalArgumentException Couldn t find PersistentEntity
  • F# 不可变的可变大小窗口数据结构

    下面是我需要的数据结构的描述 我想使用不可变的数据结构来实现它 我试图确定 是否有一个现有的数据结构可以支持我在这里尝试做的事情 或者我是否需要创建一个数据结构 如果我需要创建它 什么是好的从哪里开始 构建块 我有稳定的某种类型的传入值流
  • 如何将逻辑符号转换为 Haskell 语法

    我最近在大学学习了 Haskell 我正在做一组练习 下面是我无法理解的一个片段 考虑以下简单的前缀计算器语言的语法 num 0 1 2 3 4 5 6 7 8 9 int num num int expr int expr expr ex
  • 有条件渲染的输入组件不更新值

    使用 jsf 2 和 Primefaces 3 4 我知道有很多类似的问题 但没有一个能解决这个问题 当 panelGrid 内部 用 a 渲染时 true 的固定值
  • 如何使用 numpy 和 portaudio 提取低音、中高音

    如本例所示如何从输入音频流中提取频率信息 使用 PortAudio 我对 portaudio 和 numpy 很好奇 我对 fft 不是 100 确定 如何向 numpy 传递一个块并返回从 1 0 到 1 0 的低音 中音和高音的三个值
  • 如何使用多个LIKE运算符并使用索引

    在我的查询中 我想找到与许多 LIKE 运算符之一匹配的行 我知道 3 种方法 但只有其中一种可以使用索引 让我们从表格开始 CREATE TABLE dir id BIGSERIAL PRIMARY KEY path TEXT NOT N
  • 从 django 连接到多个 mongodb 实例

    我将 mongoengine 与 Django 结合使用 在我的项目中需要连接到两个 MongoDB 实例 同时处理单个请求 如果我使用它 效果很好 connect mdb1 do stuff with mdb1 connect mdb2
  • 如何过滤 CakePHP 中的深层关联

    我有以下表格 活页夹 文档 用户 docs users Doc 属于 Binder Doc hasAndBelongsToMany User 我想获取当前登录用户的活页夹及其关联文档 docs users 表中的关联 user id 我尝试
  • 无需 for 循环即可高效执行一维线性插值

    我正在尝试使用特定精度在 MATLAB 中执行线性插值 我想知道是否有一种有效的方法在 MATLAB 中编写线性插值函数 使其不需要 for 循环并且运行速度非常快 我想将传入的数据修改为特定的位宽 使用 quantize 函数 然后我还想
  • 将 C# double 转换为 Delphi Real48

    我发现了以下问题将 Delphi Real48 转换为 C double但我想走另一条路 从 C 到 Delphi 有谁知道如何做到这一点 我尝试过对代码进行逆向工程 但运气不佳 Update 我正在寻找 C 代码 该代码将采用 doubl
  • 导航栏/选项卡集具有反应性面板编号,但不渲染所有内容

    这个问题似乎是重复的 但让我解释一下为什么不是 我想创造一个闪亮的navbarPage具有固定元素和反应数tabPanels 对其他输入元素做出反应 关于如何创建响应式有很多问题tabsetPanels navbarPages但他们主要是为
  • 如何使用 jQuery 找到元素的绝对位置?

    有没有办法使用 jQuery 查找元素的绝对位置 即相对于窗口开头的位置 offset 将返回元素的偏移位置作为简单对象 例如 var position element offset position left 42 top 567 您可以
  • 以正确方式实现 Android Studio 3.6 时出现的 MultiDex 问题

    我将 Android Studio 更新到 3 6 在一个项目中 我遇到了 MultiDex 问题 并且不断收到此错误Calligraphy和另一个图书馆 E AndroidRuntime FATAL EXCEPTION main Proc
  • Rails:引导下拉菜单不起作用

    我对 Rails 还很陌生 并且一直在关注 Michael Hartl 的教程 一切都进展顺利 直到我进入下拉菜单 该菜单不起作用 然后起作用 现在不起作用 我已经阅读了几篇文章和修复程序 我怀疑我的修修补补已经开始了很简单 我已经做了一些
  • 将 Html.RadioButtonFor 与布尔值一起使用并不是写 Checked="Checked"

    我在使用 RadioButtonFor 帮助程序时遇到问题 当传入的值为 true 时 它 不会在任一单选按钮中显示 检查 当值为 false 时 它 工作得很好 我从我正在处理的项目中复制了这段代码并创建了一个示例应用程序 并且我能够复制
  • DCL 还坏吗?

    据我了解 旧的 JMM 实现惰性单调的 DCL 双重检查锁定 技巧已被破坏 但我认为新的 JMM 和易失性字段已修复它 然而在this不错的文章 显然足够新 可以引用新旧 JMM 和 DCL 中的易失性字段 指出它仍然损坏 我到处读到它已修