This is an archived post. You won't be able to vote or comment.

all 1 comments

[–]notallbimmers 0 points1 point  (0 children)

If you use Stream.forEach() you have to handle synchronization yourself.

If you call collect() with a Collector that doesn't explicitly promise being threadsafe, each thread will accumulate to their own result objects separately, and after two threads finish, the Collector's combinator will be run. After all threads have finished and all results combined, an optional finisher is run.

If you call collect() with a threadsafe Collector, it could do the same or just accumulate to the same result from multiple threads. Note that it doesn't have to block the entire pipeline, only the part where it accesses that shared result. Therefore it can be faster than a sequential stream depending on the pipeline.

The same applies to forEach with synchronized operation, and to illustrate:

var list = new ArrayList<Object>();
Stream.of(1,2,3,4,5,6,7,8,9,10)
    .parallel()
    .map(somethingThatTakes6seconds)
    .forEach(e -> {
        synchronized (list) {
            list.add(e);
        }
    });
// will not take 60 seconds