当前位置: 首页 > 面试题库 >

DCL是否仍然损坏?

翟聪
2023-03-14
问题内容

据我所知,使用旧的JMM来实现懒惰单调的DCL(双重检查锁定)技巧被打破了,但是我坚信它已被新的JMM和volatile字段所修复…

但是,在这篇不错的文章中,这显然已经足够新,足以引用DCL中的新旧JMM和volatile字段,表明它仍然坏了…

我在这里到那里读到它是固定的,然后我发现了这一点……有人可以最后说它是否损坏了?

我的理解是,通过波动性地在关系发生之前保证发生的先兆并有效地发出问题可以解决问题,并且DCL现在是有效的…虽然我同意静态懒惰init是可取的并且更易于理解…


问题答案:

我在这里到那里读到它是固定的,然后我发现了这一点……有人可以最后说它是否损坏了?

这取决于您所说的“它”。

如果您问是否可以使用volatile进行DCL,那么答案是是的,发布Java5。(Java的原始语义volatile没有很好html" target="_blank">定义,这意味着在volatileJava
5之前使用a 不是解决方案。)

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

如果您要问是否将DCL用于延迟初始化的单例仍然是一个好主意,那么答案是否定的(我认为):

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

  • 由于DCL习惯用法仍然容易出错并且不被很好地理解1,因此最好避免这种情况。

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

枚举和静态init将在类加载时初始化单调(如果我输入错误,请纠正我)。

我想,那你就错了。类初始化也很懒。除非您强制执行,否则它不会在上课时发生。例如,通过使用3
-精氨酸过载
Class.forName。 JLS
12.4.1列出了确定何时发生的规则。

这样做的结果是,您可以确保基于枚举的单例的初始化延迟进行,并且绝对可以安全地完成。

顺便说一句,对延迟初始化的严格要求使我想到您的应用程序设计中存在问题。至少,它引入了脆弱性……无论如何实现延迟初始化。

1-如果“普通的Joe程序员”不理解DCL的复杂性,那么在他可能需要维护的代码中使用DCL是一个坏主意。你比普通的Joe程序员更聪明。



 类似资料:
  • 我知道十进制数不能精确地用有限二进制数表示(解释),因此将失去一些精度,并且不能精确地。另一方面,可以准确地表示,因为它是。 可以理解的是,三次添加并不能准确地给出,所以下面的代码打印: 如果不能精确地表示,那么添加5次它怎么能精确地给出可以精确地表示呢?

  • 我仍然被那些为了支持移动和转发而发明的规则弄糊涂了。有一件事我还不太确定: 转发引用是否只是rvalue引用(应用了引用折叠规则)? 如果它是一个rvalue引用,那么为什么函数: 不仅接受rvalues,还接受lvalues?

  • 问题内容: 我想检查浏览器是否仍然存在,如果不存在,那么我想打开一个新的浏览器!网络驱动程序中是否有可用的api来检查浏览器是否仍然存在? 问题答案: 调用后,将driver的值设置为 但是,如果调用,它将驱动程序的值设置为 因此,如果您在调用 driver.quit() 之后检查浏览器窗口,则可以通过以下实现知道。

  • 问题内容: 是否仍然有效?我想知道本书中描述的思想,概念和实现是否仍与最新的Java版本兼容。 我问是因为最新版本是2006年完成的。 问题答案: 是的,在我看来仍然有效。从6到7的变化不大。Fork- join是一项新功能,非常适合分治法式的问题。但是本书中所有现有的东西,例如同步,易失性,servlet,仍然非常有效。

  • 问题内容: 有些人认为这样做存在一些缺陷,即使正确使用也无法保护您的查询。 带一些化石的物品作为证明。 因此,问题是:mysql [i] _real escape_string()完全不可接受吗? 还是仍然可以使用此功能来创建自己的预备语句? 请提供校对码。 问题答案: 从MySQL的C API函数描述 : 如果需要更改连接的字符集,则应使用函数而不是执行(或)语句。的工作方式类似,但也会影响所使

  • 问题内容: 我知道十进制数不能用有限的二进制数精确地表示(解释),因此会失去一些精度,并且不会精确地表示。另一方面,因为是,所以可以精确表示。 话虽如此,将 三遍 相加并不完全是可以理解的,因此,以下代码将输出: 但是, 五次 相加会得到确切的结果呢?以下代码显示: 如果不能精确表示,将其相加5次给出的精确表示又如何呢? 问题答案: 舍入误差不是随机的,并且它的实现方式会尝试使误差最小化。这意味着