2
votes

The collect operation in Java 8 Stream API is defined as a mutable reduction that can be safely executed in parallel, even if the resulting Collection is not thread safe.

Can we say the same about the Stream.toArray() method?

Is this method a mutable reduction that is thread safe even if the Stream is a parallel stream and the resulting array is not thread safe?

2
resulting Array is not thread safe - what do you mean?Andremoniy

2 Answers

5
votes

According to https://docs.oracle.com/javase/8/docs/api/java/util/stream/Stream.html#toArray-java.util.function.IntFunction- it should be since they create

... any additional arrays that might be required for a partitioned execution or for resizing

And in deduction, since Stream.toArray() is nothing but stream.toArray(Object[]::new) it should hold for Stream.toArray() too.

3
votes

The toArray operation is a kind of Mutable Reduction, though not implemented exactly like the collect operation. Instead, it’s more efficient in some cases. But these are unspecified implementation details. The documentation of toArray itself does not say anything about how it is implemented, so regarding your question, you have to resort to more general statements:

package documentation, “Parallelism”

… All streams operations can execute either in serial or in parallel.

Except for operations identified as explicitly nondeterministic, such as findAny(), whether a stream executes sequentially or in parallel should not change the result of the computation.

Most stream operations accept parameters that describe user-specified behavior, which are often lambda expressions. To preserve correct behavior, these behavioral parameters must be non-interfering, and in most cases must be stateless.

So regardless of how it’s implemented, toArray is a stream operation that can run in parallel and since it’s not specified to have any restrictions or nondeterministic behavior, it will produce the same (correct) result as in sequential mode. That’s the only thing you have to think about.

But if you use the overloaded method toArray(IntFunction), it’s your responsibility to provide an appropriate function, e.g. SomeType[]::new is always non-interfering and stateless so the form toArray(SomeType[]::new) is also thread safe.