提问者:小点点

极限无限平行流


为了证明streams.generate(supplier).limit(N)导致对supplier.get()的调用超过N次,请考虑以下代码:

public class MWE {
    static final int N_ELEMENTS=100000;
    static Supplier<IntSupplier> mySupplier = () -> new IntSupplier() {
        AtomicInteger ai = new AtomicInteger(-1);
        @Override
        public int getAsInt() {
            return ai.incrementAndGet();
        }
    };
    public static void main(String[] args) {
        int[] a = IntStream.generate(mySupplier.get()).limit(N_ELEMENTS).toArray();
        int[] b = IntStream.generate(mySupplier.get()).parallel().limit(N_ELEMENTS).toArray();
    }
}

A与预期的一样等于[0,1,...,N_ELEMENTS-1],但与预期相反,B不包含与A相同的元素。相反,b通常包含大于或等于n_elements的元素,这表示对供应商的调用次数多于n_elements

另一个例子是streams.generate(new Random(0)::nextdouble()).limit(5)并不总是生成相同的一组数字。


共1个答案

匿名用户

流API不能保证intstream.generate()调用生成器指定的次数。而且这个电话不尊重命令。

如果您确实需要一个数字递增的并行流,那么最好使用intstream.range(0,N_ELEMENTS).parallex()。这不仅确保您实际上拥有从0n_elements-1的所有数字,而且大大减少了争用并保证了顺序。如果需要生成更复杂的内容,可以考虑使用自定义源代码定义自己的拆分器类。

请注意,建议的intstream.iterate解决方案可能并行化程度不高,因为它是按自然顺序的源代码。