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.
-Doug
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.