问题标签 [double-checked-locking]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
java - 双重检查锁定文章
我正在阅读这篇关于“双重检查锁定”的文章,并且在文章的主题之外,我想知道为什么在文章的某些地方作者使用了下一个成语:
清单 7. 尝试解决乱序写入问题
我的问题是:有什么理由用同一个锁同步两次代码吗?这有什么目的吗?
提前谢谢了。
java - 使用双重检查习语重置延迟加载的字段
考虑“实例字段延迟初始化的双重检查习惯用法”:
/blockquote>我希望能够以安全的方式重置该字段(在我的情况下,强制它从数据库中再次加载)。我假设我们可以通过使用重置方法来做到这一点:
/blockquote>这是重置字段的标准方法吗?安全吗?有什么陷阱吗?我之所以问,是因为 Bloch 就双重检查延迟加载给出了以下警告:“这个习语非常快,但也很复杂和微妙,所以不要试图以任何方式修改它。只需复制和粘贴——通常不是一个好主意,但在这里很合适。”
提前感谢来自喜马拉雅山的普拉亚。
java - 这是损坏的双重检查锁定吗?
Checkstyle 将此代码报告为“双重检查锁定习惯用法已损坏”,但我认为我的代码实际上并未受到双重检查锁定问题的影响。
如果不存在具有该 id 的行,则该代码应该在数据库中创建一行。它在多线程环境中运行,我想避免主键存在 SQL 异常。
伪代码:
我同意它看起来像双重检查锁定,但我没有使用静态变量,并且 fetch() 和 create() 中的代码可能太复杂而无法内联和乱序。
我错了还是检查式?:)
.net - .NET 中的双重检查锁定
我看到这篇文章讨论了为什么 Java 中的双重检查锁定范式被破坏了。如果声明了变量,范式是否适用于 .NET(特别是 C#)volatile
?
coldfusion - “双重检查锁定”在 ColdFusion 中有效吗?
我在我的 CF 应用程序中使用了双重检查锁定版本(在我知道双重检查锁定是什么之前)。
本质上,我检查对象的存在。如果它不存在,我会锁定(通常使用命名锁)并在尝试创建对象之前再次检查是否存在。我认为这是一种停止创建多个对象并停止在系统中过度锁定的巧妙方法。
这似乎可行,因为没有过多的锁定并且不会创建对象重复项。但是,我最近了解到Double Checked Locking 在 Java 中不起作用,我不知道这在 CF 中是否成立,因为 CF 线程和锁与本机 Java 线程和锁并不完全相同。
multithreading - 双重检查锁定的修复有什么问题?
因此,我现在看到很多文章声称在 C++ 双重检查锁定(通常用于防止多个线程尝试初始化延迟创建的单例)上已损坏。正常的双重检查锁定代码如下所示:
问题显然是行分配实例——编译器可以自由地分配对象,然后分配指针给它,或者将指针设置到它将被分配的位置,然后分配它。后一种情况打破了惯用语——一个线程可以分配内存并分配指针,但在它进入睡眠状态之前不运行单例的构造函数——然后第二个线程将看到实例不为空并尝试返回它,即使它尚未构建。
我看到一个建议使用线程本地布尔值并检查它而不是instance
. 像这样的东西:
这样,每个线程最终都会检查实例是否已创建一次,但在此之后停止,这会导致一些性能损失,但仍然没有锁定每个调用那么糟糕。但是如果我们只使用本地静态布尔值呢?
为什么这行不通?即使 sync_check 在被分配到另一个线程时被一个线程读取,垃圾值仍然是非零的,因此为真。Dobb 博士的这篇文章声称您必须锁定,因为您永远不会在重新排序指令上与编译器进行战斗。这让我认为由于某种原因这一定行不通,但我不知道为什么。如果对序列点的要求像 Dobb 博士的文章让我相信的那样丢失,我不明白为什么锁之后的任何代码都不能重新排序到锁之前。这将使 C++ 多线程中断期。
我想我可以看到编译器被允许专门将sync_check重新排序到锁之前,因为它是一个局部变量(即使它是静态的,我们也没有返回指向它的引用或指针)——但这仍然可以解决通过使其成为静态成员(实际上是全局的)来代替。
那么这会起作用还是不会呢?为什么?
java - Java 双重检查锁定
我最近偶然看到一篇文章,讨论了 Java 中的双重检查锁定模式及其陷阱,现在我想知道我多年来一直使用的该模式的变体是否会遇到任何问题。
我查看了许多关于该主题的帖子和文章,并了解获取对部分构造对象的引用的潜在问题,据我所知,我认为我的实现不受这些问题的影响。以下模式有什么问题吗?
而且,如果没有,为什么人们不使用它?在我看到的围绕这个问题的任何讨论中,我从未见过它被推荐过。
java - Java通过强制同步两次来双重检查锁定,可行吗?
我已经阅读了有关双重检查锁定修复如何从不工作的所有内容,并且我不喜欢延迟初始化,但是能够修复遗留代码会很好,而且这样的问题太诱人了,无法尝试解决。
这是我的例子: private int timesSafelyGotten = 0; 私人助手 helper = null;
这样,同步代码必须运行一次以创建帮助程序,并且在第一次获取它时运行一次,因此理论上 timesSafelyGotten 不能递增,直到创建帮助程序的同步代码释放锁并且帮助程序必须完成初始化。
我认为没有问题,但它是如此简单,看起来好得令人难以置信,你怎么看?
迦勒·詹姆斯·德莱尔
c++ - 三重检查锁定?
因此,与此同时,我们知道双重检查锁定在 C++ 中不起作用,至少不能以可移植的方式工作。
我刚刚意识到我在用于地形光线追踪器的惰性四叉树中有一个脆弱的实现。所以我试图找到一种仍然以安全的方式使用延迟初始化的方法,因为我不想将内存使用量翻两番并重新排序大部分已实现的算法。
这种遍历的灵感来自C++ 第 12 页上的模式和双重检查锁定的风险,但尝试以更便宜的方式进行:
假设这#pragma flush
也将作为一个硬序列点,不允许编译器和处理器在它们之间重新排序操作。
你看到了哪些问题?
编辑:版本 2,试图考虑 Vlads 的回答(引入第三次刷新):
编辑:版本 3,不知何故,我发现这与版本 2 相当,因为我没有使用孩子本身,而是使用原始标志来检查有效性,基本上依赖于创建孩子和写入该标志之间的内存屏障。
objective-c - Mike Ash Singleton:放置@synchronized
我在 Mike Ash “单身人士的照顾和喂养”中遇到了这个问题,他的评论让我有些困惑:
不过,这段代码有点慢。拿锁有点贵。更痛苦的是,在绝大多数情况下,锁是没有意义的。只有当 foo 为 nil 时才需要锁,这基本上只发生一次。初始化单例后,不再需要锁,但锁本身仍然存在。
我的问题是,这毫无疑问是有充分理由的,但你为什么不能写(见下文)将锁限制在 foo 为 nil 时?
干杯加里