gpt4 book ai didi

java - 在多线程(Java 或 .Net)程序中,我可以假设复制变量是原子的吗?

转载 作者:塔克拉玛干 更新时间:2023-11-03 04:40:24 28 4
gpt4 key购买 nike

当我想知道这个问题时,我正在担心我正在设计的应用程序中的竞争条件。

假设我有一个大型数组或某种集合,由我的程序的一个组件管理,我们称该组件为 Monitor。它的工作是定期检查集合是否“脏”,即。 e.最近发生了变化,如果是这样,将快照写入磁盘(这是为了在发生崩溃时检查应用程序)并再次将其标记为干净。

同一程序的其他组件,运行在不同的线程中,调用监视器的方法向数组/集合中添加数据或修改数据。这些方法将集合标记为脏。

现在,更改方法在其他组件的线程中运行,对吧?如果我不那么幸运,它们可能会在快照写入磁盘时被调用,更改已经写入的数据,设置脏标志,然后监视器的线程将其取消设置,而不会保存更改(它改变时已经超过了元素)。所以我有一个标记为干净的脏集合。

有一段时间,我认为我可以通过制作一个集合的临时副本来解决问题,将其标记为干净,然后去序列化副本。但是复制是原子的吗? e.我可以确保在复制时集合不会发生变化吗?

与此同时,我想我找到了更好的解决方案,比如

  • 在开始写入磁盘之前设置一个锁定标志,并让数据更改方法等到标志被取消设置
  • 让数据更改方法写入“更改队列”而不是直接写入集合,并让线程执行该队列的磁盘写入过程

而且我认为锁定标志可能是最好的方法。 但我还是很好奇:复制变量是原子的吗?


跟进:也许这应该放在一个单独的问题中,但实际上它非常相似。根据下面的答案,我的“锁定标志”方法可能也行不通,对吧?因为数据更改方法可能会在将锁定标志设置为“锁定”值时检查锁定标志并确定它未锁定。所以如果我真的想正确地做这件事,我需要一个像互斥锁这样的特殊结构,对吗?


感谢 erickson为他的very helpful answer在我的后续行动中。我真的应该提出这两个问题,这样我才能接受两个答案。请也给他投票。

最佳答案

没有。例如,Java 中的长变量在 32 位机器上不是原子的。

此外,还有一个“线程缓存”问题 - 除非您的变量是可变的或在同步块(synchronized block)内,否则另一个线程可能看不到变量值的更改。这适用于所有类型的变量,而不仅仅是 long。

阅读此处:http://gee.cs.oswego.edu/dl/cpj/jmm.html ,尤其是“原子性”和“可见性”段落。

关于java - 在多线程(Java 或 .Net)程序中,我可以假设复制变量是原子的吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/473111/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com