gpt4 book ai didi

java - 在 ConcurrentModificationException 之后,Java 集合是否保证处于有效、可用的状态?

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

我正在使用 Immediate Mode GUI pattern 编写一个 GUI 应用程序,并且 UI 在独立于为应用程序的实际功能提供支持的引擎的线程上运行。 GUI 线程最终迭代许多概念上由引擎线程“拥有”的对象列表,并且这些列表极少更改。 GUI 线程是垂直同步的,这意味着它以大约 60Hz 的频率运行,而引擎线程以大约 200Hz 的频率运行。

有时,UI 中的操作会更改引擎中集合的内容,我有一个消息传递系统将 Runnable 发布到引擎线程以执行这些突变,以确保这些突变不会与引擎中的内容发生冲突发生在引擎中。这样,我可以确保引擎始终看到一致的数据 View ,这对我的应用程序非常重要。

因为引擎负责所有的数据变化,所以有时引擎会在 GUI 遍历集合时更改集合的内容,并且因为这些集合是标准的 Java 集合,这可以预测并正确地抛出一个ConcurrentModificationException .我可以想到一些高级方法来处理这个问题:

  1. 锁定,通过使用同步集合或读写锁
  2. 双缓冲 GUI 线程读取的数据,并让 GUI 线程在完成绘制帧时翻转双缓冲区
  3. 忽略 CME 并中止绘制剩余的帧,这将为发生“坏”突变的帧绘制部分信息,然后继续下一帧

锁定会带来显着的性能损失,虽然 GUI 在等待从引擎线程获取锁时有时会停止是可以的,但引擎线程以一致的速度运行非常重要,并且即使是 R/W 锁也会导致引擎线程停顿。双缓冲带来了显着的复杂性,因为 GUI 在每一帧上读取了很多数据。

我向您介绍了所有这些背景知识,因为我知道选项 3 很丑陋,而且我的问题在某种意义上“不是正确的问题”。 ConcurrentModificationException 的 Javadoc甚至说:

Note that fail-fast behavior cannot be guaranteed as it is, generally speaking, impossible to make any hard guarantees in the presence of unsynchronized concurrent modification. Fail-fast operations throw ConcurrentModificationException on a best-effort basis. Therefore, it would be wrong to write a program that depended on this exception for its correctness: ConcurrentModificationException should be used only to detect bugs.

但是!我不关心会被 CME 破坏的单帧 GUI 的正确性。我只关心下一帧会发生什么。这引出了我的问题:在 ArrayList 之后继续使用 Java 集合是否安全(我最感兴趣的是 HashMapConcurrentModificationException 的答案)已从其迭代器中抛出?这似乎是合乎逻辑的,但我找不到一份文档说在抛出 CME 后该对象仍将处于可用状态。显然,此时迭代器已经完蛋了,但我想吞下这个异常并继续使用该集合。

最佳答案

引用部分引述:

Therefore, it would be wrong to write a program that depended on this exception for its correctness: ConcurrentModificationException should be used only to detect bugs.

结论:您的代码有问题,需要修复,因此集合处于什么状态并不重要。

你应该永远在有效代码中得到那个错误。这是一个永远不应该被捕获和采取行动的异常。

关于java - 在 ConcurrentModificationException 之后,Java 集合是否保证处于有效、可用的状态?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55286705/

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