0

I have an executer service with a thread pool of 3 and each thread is accessing a synchronizedList and converting it to a list of Map

List<String> fruitList = Collections.synchronizedList(new ArrayList<>());
fruitList.add("banana");
fruitList.add("banana");
fruitList.add("banana");
fruitList.add("banana");
fruitList.add("kiwi");
fruitList.add("mango");
fruitList.add("mango");
fruitList.add("papaya");

I want to convert this list to a list of map where fruitName will be key and frequency of item will be the value

[{"banana" : 4}, {"mango" : 2}, {"kiwi" : 1}, {"papaya" :1}]

I tried something like this

Map<String, Long> fruitMap = fruitList.stream().collect(Collectors.
                        groupingBy(e -> e, Collectors.counting()));

But, occasionally I am getting the following error. How can I resolve this?

[java] Exception in thread "pool-3-thread-3" java.util.ConcurrentModificationException
     [java]     at java.util.ArrayList$ArrayListSpliterator.forEachRemaining(ArrayList.java:1388)
     [java]     at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:482)
     [java]     at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:472)
     [java]     at java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:708)
     [java]     at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
     [java]     at java.util.stream.ReferencePipeline.collect(ReferencePipeline.java:566)
1
  • 1
    Could you share the complete code to reproduce this? Commented Jul 6, 2020 at 6:18

1 Answer 1

1

If fruitList is updated in the middle of .stream().collect() process, you shall get that exception. A proper critical section definition and synchronization should be created to avoid that.

Although Collections.synchronizedList() does synchronization for most of the methods, it does not synchronize Collection.stream() and other methods on the stream. You need to synchronize your stream process manually.

That should work:

synchronized(fruitList) {
    Map<String, Long> fruitMap = fruitList.stream()
                       .collect(Collectors.groupingBy(e -> e, Collectors.counting()));
}
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.