Java 8 ConcurrentModificationException on any iteration

Trying to find out this problem within 2 weeks, but without any success .: X

This happens when I do any iteration, but mostly when using #forEach.

I do not modify the list, nor its elements, so this seems to me very inconvenient. Code example:

Map<Season, List<Team>> map = fetcher.getTeamsIn(ids); Set<Team> toCreateTeams = new HashSet<>(); Set<Team> toUpdateTeams = new HashSet<>(); map.forEach((k, v) -> { toCreateTeams.addAll(v.stream().filter(t -> !persistedTeams.containsKey(t.getId())).collect(Collectors.toSet())); toUpdateTeams.addAll(v.stream().filter(t -> { Date latestPersistedUpdate = persistedTeams.get(t.getId()); return latestPersistedUpdate != null && t.getLastUpdated().after(latestPersistedUpdate); }).collect(Collectors.toSet())); }); 

an instance is created in #getTeamsIn using new HashMap<>();

Tried to break the exception in eclipse to see if some kind of crazy crap stream is working, but everything seems normal to me. In the figures below, an exception was thrown when repeating map .

ConcurrentModificationException thread stack traceConcurrentModificationException thread stack trace

I started another very strange behavior, for example, getting stuck in a lambda expression forever. In this case, it seems to me that Eclipse stops in the expression (for some unknown reason), as if some kind of breakpoint was set in the line. When I pause execution and resume only the problematic thread, the thread just returns to its normal state (until the next lambda expression) or some crazy ConcurrentModificationException.

stopping in expression for unknown reason

All of this seems like a crazy Eclipse mistake to me, but I really don't want to rebuild my environment if that is the case.

I use

 Java(TM) SE Runtime Environment (build 1.8.0_45-b14) Java HotSpot(TM) 64-Bit Server VM (build 25.45-b02, mixed mode) 

on Linux Mint.

Thanks!

- Update 1 -

Just to be clear: an error occurs even for this simple example:

 map.forEach((k, v) -> { System.out.println("Test" + k.getId()); }); 

Some random information that could be important: the exception only exploded after printing the last card element!

- Update 2 -

Regarding the random information in Update 1, this is really inconsequential, because for performance reasons (at least in HashMap and ArrayList) ConcurrentModificationException checked only at the end of iterations, comparing the actual size of the array of elements with the expected size.

The code of the #getTeamsIn method:

 public Map<Season, List<Team>> getTeamsIn(List<Season> seasons) throws InterruptedException { final CountDownLatch latch = new CountDownLatch(seasons.size()); Map<Season, List<Team>> teamsInSeason = new HashMap<>(); for (Season s : seasons) { httpclient.execute(new HttpGet(String.format(URL, s.getId())), new Callback(latch) { @Override public void completed(final HttpResponse response) { super.completed(response); try { teamsInSeason.put(s, new TeamsUnmarshaller().unmarshal(response.getEntity().getContent())); } catch (IllegalStateException | IOException e) { // TODO Auto-generated catch block System.out.println(e); } } }); } latch.await(); return teamsInSeason; } 

Callback class just implements FutureCallback<HttpResponse> and countDown() latch in all callback methods (#cancelled, #completed and #failed).

+6
source share
1 answer

Ok, just figured out the problem. My overridden # finished method in the #getTeamsIn method takes too much time (thanks to JAXB) to return. Since countDown() (called in super.completed(response) ) before teamsInSeason.put(s, new TeamsUnmarshaller().unmarshal(response.getEntity().getContent())); , we have a problem.

The fix is ​​simple and ugly:

 @Override public void completed(final HttpResponse response) { try { teamsInSeason.put(s, new TeamsUnmarshaller().unmarshal(response.getEntity().getContent())); } catch (IllegalStateException | IOException e) { // TODO Auto-generated catch block System.out.println(e); } finally { super.completed(response); } } 

It seems that the strange behavior of Eclipse (stuck at some imaginary breakpoint for some unknown reason), if it persists, is a problem for another topic.

Thank you all for your help and time!

+3
source

Source: https://habr.com/ru/post/986094/


All Articles