使用collect时的并发数据结构和并行流

时间:2018-04-18 12:03:03

标签: lambda java-8 java-stream

在完成以下有关using concurrent data structures in streamsdifferent between using concurrent map and converting to a map的答案后,有人可以解释如果我使用collect的其他语法,即会发生什么。

    Stream<Integer> integers = Stream.iterate(1, n -> n + 1).parallel(); 
    Map<Integer, Boolean> resultMap = integers
                                        .limit(1000)
                                        .collect(HashMap::new,
                                                (map, value) -> map.put(value, false),
                                                HashMap::putAll);

根据文档,将根据生成的线程数调用供应商。如果我使用ConcurrentHashMap而不是HashMap怎么办?

  

当并行执行时,可能会有多个中间结果   实例化,填充和合并以便保持隔离   可变数据结构。因此,即使并行执行   使用非线程安全的数据结构(如ArrayList),没有   并行缩减需要额外的同步。

2 个答案:

答案 0 :(得分:5)

使用{-1}}代替ConcurrentHashMap时,使用三个{arg HashMap方法时,不会发生任何行为更改。要更改行为,您需要collect来报告CONCURRENT特征,并且无法使用ad-hoc收集器指定特征。

此外,操作必须是无序的,以启用并行收集操作,其中所有线程累积到单个容器中。由于流属性,该操作可能是无序的,或者是本质上,例如,在Collector之类的无序来源上流式传输时,或通过HashSet显式流式传输,例如

unordered()

或由于收集者的Map<Integer, Boolean> resultMap = integers.limit(1000) .unordered() .collect(Collector.of( () -> new ConcurrentHashMap<>(), (map, value) -> map.put(value, false), (m1,m2) -> { m1.putAll(m2); return m1; }, Collector.Characteristics.CONCURRENT)); 特征:

UNORDERED

后者是你在使用内置收集器时得到的:

Map<Integer, Boolean> resultMap = integers.limit(1000)
    .collect(Collector.of(
        () -> new ConcurrentHashMap<>(),
        (map, value) -> map.put(value, false),
        (m1,m2) -> { m1.putAll(m2); return m1; },
        Collector.Characteristics.CONCURRENT, Collector.Characteristics.UNORDERED));

Map<Integer, Boolean> resultMap = integers.limit(1000) .collect(Collectors.toConcurrentMap(Function.identity(), i -> Boolean.FALSE)); 始终为toConcurrentMapCONCURRENT,当您使用地图供应商时需要UNORDERED,而ConcurrentMap永远不会toMap即使您提供了创建CONCURRENT实施实例的供应商。

答案 1 :(得分:2)

准确地说,即使你使用ConcurrentHashMap个线程,也不会共享数据,并且会有尽可能多的ConcurrentHashMap,因为supplier将被称为no。时间。 combiner即最后一个BiConsumer参数将执行合并操作但是没有顺序,即无论哪个线程完成抛出数据,然后合并。

当你明确地说Collectors.toConcurrentMap时,收集器行为是一个单个容器(即ConcurrentHashMap)所有线程将推送数据&amp;不需要合作。