Exceptional behavior of parallel stream
Tagir F. Valeev
amaembo at gmail.com
Wed Aug 17 13:01:05 UTC 2016
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:
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