Random.ints()をdistinct()+parallel()に繋ぐと動かなかった


Random.ints()の戻り値のIntStreamをdistinct()とparallel()に食わすと戻ってこなくなる。

下のようなJavaのプログラムを動かすと、なぜか8つの数字が出力された時点で止まってしまった戻ってこなくなります。

serial
2
1
0
3
parallel
3
0
3
2
parallel + distinct ←ここで止まって戻ってこない。

 問題のコード

distince()とparallel()を同時に使うときだけ問題が発生するようです。

import java.util.*;
public class testParallel {
    //sequential
    static void printRandom(){
        Random rint = new Random();
        rint.ints(0,4)
            .distinct()
            .limit(4)
            .forEach(System.out::println);
    }
    //parallel
    static void printRandomParallel(){
        Random rint = new Random();
        rint.ints(0,4)
            .limit(4)
            .parallel()
            .forEach(System.out::println);
    }
    //parallel+distinct
    static void printRandomParallelDistinct(){
        Random rint = new Random();
        rint.ints(0,4)
            .distinct()
            .limit(4)
            .parallel()
            .forEach(System.out::println);
    }
    public static void main(String[] args){
        System.out.println("serial");
        printRandom();
        System.out.println("parallel");
        printRandomParallel();
        System.out.println("parallel + distinct");
        printRandomParallelDistinct();
    }
}

対策

自前でIntStreamを生成したらうまく動いたというお話でした。
理由は良くわかりません。

import java.util.*;
import java.util.stream.*;
public class testParallel2 {
    static void printRandomParallel(){
        getRandomStream(4)
            .distinct()
            .limit(4)
            .parallel()
            .forEach(System.out::println);
    }
    static IntStream getRandomStream(int max){
        PrimitiveIterator.OfInt p = new PrimitiveIterator.OfInt(){
            Random r = new Random();
            @Override
            public boolean hasNext(){
                return true;
            }
            @Override
            public int nextInt(){
                int ret = r.nextInt(max);
                return ret;
            }
        };
        Spliterator.OfInt sp = Spliterators.spliteratorUnknownSize(p,0);
        IntStream ints = StreamSupport.intStream(sp,false);
        return ints;
    }
    public static void main(String[] args){
        printRandomParallel();
    }
}

結果

1
3
2
0

動作環境

java version "1.8.0_101"
Java(TM) SE Runtime Environment (build 1.8.0_101-b13)
Java HotSpot(TM) 64-Bit Server VM (build 25.101-b13, mixed mode)