对《Java 8 in Action》中CONCURRENT Collector并行条件的疑问
关于《Java 8 in Action》中ToListCollector并行处理的疑问解析
先来看《Java 8 in Action》里作者实现的ToListCollector类代码:
class ToListCollector<T> implements Collector<T, List<T>, List<T>> { @Override public Supplier<List<T>> supplier() { return ArrayList::new; } @Override public BiConsumer<List<T>, T> accumulator() { return List::add; } @Override public BinaryOperator<List<T>> combiner() { return (l1, l2) -> { l1.addAll(l2); return l1; }; } @Override public Function<List<T>, List<T>> finisher() { return Function.identity(); } @Override public Set<Characteristics> characteristics() { return Collections.unmodifiableSet(EnumSet.of(Characteristics.IDENTITY_FINISH, Characteristics.CONCURRENT)); } }
作者对这个收集器的特性解释是:
它是IDENTITY_FINISH和CONCURRENT,但非UNORDERED,因为应用于有序流时需保留顺序;同时称仅当底层数据源无序时,流才会被并行处理。
你这个疑问抓得非常准——有序流完全可以并行处理,书籍里“仅当底层数据源无序时,流才会被并行处理”的说法确实不准确。
并行处理有序流的核心是combiner()方法要正确维护元素的顺序,就像这个ToListCollector里的实现一样:把分段处理得到的第二个列表的元素全部追加到第一个列表后面,这样最终合并后的结果就能和原有序流的元素顺序完全一致。
Java并行流的核心设计者也明确提到过,有序流同样支持并行处理,只是在并行执行过程中,框架需要额外维护元素的顺序信息,可能会带来一些性能损耗,但这绝对不代表有序流不能被并行处理。
内容的提问来源于stack exchange,提问作者Coder-Man
相关产品推荐
相关产品推荐

