【问题标题】:ConcurrentModificationException while making .removeAll() method制作 .removeAll() 方法时出现 ConcurrentModificationException
【发布时间】:2021-08-14 18:31:43
【问题描述】:

我的代码看起来像这样

public class ListAnalyzer {
public static List<String> base;

public static void addOfflineToBase(String offline) {
    base.add(offline);
}

public static List<String> prepareArrayList() throws IOException {
    base = Files.readAllLines(Paths.get("/Users/noname/Desktop/test.txt").toAbsolutePath().normalize());
    List<String> part = base.subList(0, 200);
    base.removeAll(part);
    saveBase();
    return part;
}

当我尝试运行它时 - 我看到了:

Unable to evaluate the expression Method threw 'java.util.ConcurrentModificationException' exception.

当我尝试 base.removeAll(part) 时在线 我在这里看不到冲突。有人能帮助我吗? 顺便说一句:saveBase() 只是将数据写入文本文件 UPD:堆栈跟踪

21:59:26: Executing task 'App.main() --scan'...

> Task :compileJava UP-TO-DATE
> Task :processResources NO-SOURCE
> Task :classes UP-TO-DATE

> Task :App.main() FAILED
2 actionable tasks: 1 executed, 1 up-to-date

Publishing a build scan to scans.gradle.com requires accepting the Gradle Terms of Service defined at https://gradle.com/terms-of-service. Do you accept these terms? [yes, no] Exception in thread "main" java.util.ConcurrentModificationException
 at java.base/java.util.ArrayList$SubList.checkForComodification(ArrayList.java:1445)
 at java.base/java.util.ArrayList$SubList.size(ArrayList.java:1185)
 at java.base/java.util.AbstractCollection.isEmpty(AbstractCollection.java:87)
 at com.lukaspradel.steamapi.webapi.request.GetPlayerSummariesRequest$GetPlayerSummariesRequestBuilder.<init>(GetPlayerSummariesRequest.java:41)
 at hexlet.code.App.getOnlineIds(App.java:39)
 at hexlet.code.App.start(App.java:21)
 at hexlet.code.App.main(App.java:16)

FAILURE: Build failed with an exception.

* What went wrong:
Execution failed for task ':App.main()'.
> Process 'command '/Library/Java/JavaVirtualMachines/zulu-11.jdk/Contents/Home/bin/java'' finished with non-zero exit value 1

* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output. Run with --scan to get full insights.

* Get more help at https://help.gradle.org

BUILD FAILED in 337ms

```lang-none

【问题讨论】:

  • 您将列表标记为静态。您班级的所有实例共享相同的列表库
  • 我没有这个类的任何实例。我只是像存储一样使用它
  • 请发布完整的堆栈跟踪。
  • @RaviKThapliyal 请检查 UPD
  • ConcurrentModificationException 的原因可能是在更改同一集合时尝试迭代集合(在本例中为列表)。如需更多帮助,请发帖minimal reproducible example

标签: java list arraylist concurrentmodificationexception


【解决方案1】:

我需要了解如何安全地从 base 中删除字符串。

有两种方式:

  1. 添加一些应用程序级别的锁定,这样您就不会尝试从列表中删除字符串,而其他东西正在迭代列表。

  2. 使用并发集合类型而不是List。 (不清楚哪种集合类型最合适。没有合适的并发列表类型;即支持高效更新的类型。)并发集合类型在java.util.concurrentpackage 中定义。

【讨论】:

    【解决方案2】:

    我想问题出在以下几行:

    List<String> part = base.subList(0, 200);
    base.removeAll(part);
    

    part 列表实际上是由base 列表支持的,所以base 的变化会反映在part 中。这可能会导致此类异常。

    要确认,请尝试一下:

    List<String> part = new ArrayList<>(base.subList(0, 200));
    base.removeAll(part);
    

    另一种可能性,它做的事情不同,但与你的相似:

     base.subList(0, 200).clear();
    

    这将删除 0 到 200 范围内的所有元素,前提是所有元素都是唯一的。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-03-24
      • 2018-01-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-07-15
      相关资源
      最近更新 更多