Exceptional behavior of parallel stream

Doug Lea dl at cs.oswego.edu
Thu Aug 18 10:54:32 UTC 2016

On 08/17/2016 09:01 AM, Tagir F. Valeev wrote:
> Hello!
> I found no information in Stream API documentation on how it behaves
> in case if exception occurs during the stream processing. While it's
> quite evident for sequential stream (stream processing is terminated
> and exception is propagated to the caller as is), the behavior for
> parallel streams differs from one might expect. Consider the following
> test:

In your example, you can witness the delayed termination of other threads
upon exception in another because you add side-effecting operations
(here, just printing). Avoiding all this would force sequential processing.

But if the supplied functions follow the documented properties,
it should not matter that parallel processing of some elements continues
when another hits an exception. Which is why nothing is said about it.
Similar effects occur in findAny and other methods. I don't see any benefit
in trying to specify exactly what happens in these cases.


> String[] data = IntStream.range(0, 100).mapToObj(String::valueOf)
>                          .toArray(String[]::new);
> data[20] = "oops";
> try {
>     int sum = Arrays.stream(data).parallel().mapToInt(Integer::valueOf)
>                     .peek(System.out::println).sum();
>     System.out.println("Sum is "+sum);
> } catch (NumberFormatException e) {
>     System.out.println("Non-number appeared!");
> }
> This parses integers stored in string array and sums them outputting
> every number to stdout once it processed. As data set contains
> non-number, the stream obviously fails with NumberFormatException. The
> typical output looks like this:
> 62
> 63
> 12
> 31
> 87
> ...
> 28
> 92
> 29
> 8
> Non-number appeared!
> 9
> 30
> So as you can see, the stream is not actually terminated when
> exception is thrown and caught: even after that some parallel tasks
> continue running, and you see more numbers printed after catch block
> is executed.
> I consider such behavior as confusing and unexpected. Given the fact
> that stream may produce side-effects (e.g. if terminal op is forEach)
> this might lead to unforeseen consequences in user programs as
> left-over parallel stream tasks may continue mutate shared state after
> main stream thread exceptionally returns the control to the caller.
> So I suggest that such behavior should be either fixed or explicitly
> documented. What do you think?
> With best regards,
> Tagir Valeev.

More information about the core-libs-dev mailing list