On 4 Aug 2015, at 09:20, Paul Sandoz <paul.san...@oracle.com> wrote:

> 
> On 4 Aug 2015, at 01:09, Stuart Marks <stuart.ma...@oracle.com> wrote:
> 
>> Hi Tagir,
>> 
>> Interesting issues.
>> 
>> Regarding Stream.concat, it may be that, today, changes to the 
>> sequential/parallel execution mode aren't propagated to the streams being 
>> concatenated.
> 
> The execution mode is propagated if either stream to concat is parallel i.e. 
> isParallel()
> 
> The issue here is that Stream.spltierator() is a form of terminal operation 
> that will result in pipeline evaluation if there are non-lazy stateful 
> operations present.
> 
> What we don’t currently do is propagate the parallelism back to a sequential 
> stream when the other is a parallel stream. We could easily do that as a bug 
> fix. I agree with Stuart it does not require any specification e.g.:
> 
> public static <T> Stream<T> concat(Stream<? extends T> a, Stream<? extends T> 
> b) {
>    Objects.requireNonNull(a);
>    Objects.requireNonNull(b);
> 
>    boolean isPar = a.isParallel() || b.isParallel();
>    @SuppressWarnings("unchecked")
>    Spliterator<T> split = new Streams.ConcatSpliterator.OfRef<>(
>            (Spliterator<T>) (isPar ? a.parallel() : a).spliterator(),
>            (Spliterator<T>) (isPar ? b.parallel() : b).spliterator());
>    Stream<T> stream = StreamSupport.stream(split, isPar);
>    return stream.onClose(Streams.composedClose(a, b));
> }
> 

And on reflection this may not always be the right thing to do, there are 
surprises either way. I am leaning towards not doing this and Stream.concat 
should obey the mode of the stream that is passed to it in terms of each 
evaluation. Thereby it is explicit as per what the caller declared.

It’s probably too late to specify that, but we could and something to the 
@implNote stating the current implementation behaviour and add an @apiNote on 
guaranteeing parallel execution of the two streams to concat.

Paul.

Reply via email to