javalistarraylistconcurrentmodificationexception

ConcurrentModificationException while making .removeAll() method


I have code looks like this

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;
}

And when i try to run it - i see:

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

On the line when i try to base.removeAll(part) I can`t see conflict here. Can someone help me, please? BTW: saveBase() just writes data to textfile UPD: Stacktrace

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

Solution

  • I need to understand how i can safely remove strings from base.

    There are two ways:

    1. Add some application level locking so that you don't try to remove strings from the list while something else is iterating the list.

    2. Use a concurrent collection type instead of a List. (It is not clear what collection type would be most appropriate. There isn't a suitable concurrent list type; i.e. one that supports efficient update.) The concurrent collection types are defined in the java.util.concurrent package.