java - 这个 IntStream 分区实现真的不是线程安全的吗?

标签 java multithreading concurrency java-stream

answer提供对 IntStream 进行分区的实现:

IntStream intStream = IntStream.iterate(0, i -> i + 1).limit(1000000);

Predicate<Integer> p = x -> r.nextBoolean();
Map<Boolean, List<Integer>> groups = intStream.collect(() -> {
    Map<Boolean, List<Integer>> map = new HashMap<>();
    map.put(false, new ArrayList<>());
    map.put(true, new ArrayList<>());
    return map;
}, (map, x) -> {
    boolean partition = p.test(x);
    List<Integer> list = map.get(partition);
    list.add(x);
}, (map1, map2) -> {
    map1.get(false).addAll(map2.get(false));
    map1.get(true).addAll(map2.get(true));
});

System.out.println(groups.get(false).size());
System.out.println(groups.get(true).size());

但是它的编辑提到这个实现不是线程安全的。然而,据我所知,收集器创建了一个单独的 HashMap<List<Integer>>对于并行流中的每个线程。所以每个映射都被限制在一个线程中。分区功能也仅限于单个线程。合并函数合并来自多个线程的结果,但据我所知,流框架确保合并以线程安全的方式完成。所以我的问题是:这个解决方案真的不是线程安全的吗?

顺便说一句:无论如何,答案提供了一个更优雅的解决方案(Stream<Integer> stream = intStream.boxed(); 等),但我仍然想知道。

PS:我想将这个问题添加为对原始帖子的评论,但我什至没有添加评论的声誉...:|

最佳答案

根据 Oracles 文档

Like reduce(int, IntBinaryOperator), collect operations can be parallelized without requiring additional synchronization.

https://docs.oracle.com/javase/8/docs/api/java/util/stream/IntStream.html#collect-java.util.function.Supplier-java.util.function.ObjIntConsumer-java.util.function.BiConsumer-

看来您的直觉是正确的,这是线程安全的。

关于java - 这个 IntStream 分区实现真的不是线程安全的吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61251704/

相关文章:

c# - 尝试并行运行多个 HTTP 请求,但受到 Windows(注册表)的限制

multithreading - Akka如何达到如此高的性能?

ios - 主队列上的调度屏障

Java 并发实践 : 3. 5.4 有效不可变对象(immutable对象):我们是否需要线程安全集合容器来存储有效不可变对象(immutable对象)

scala - 如何并行执行多个任务?

java - 在 jMonkey 中更改相机行为

java - 在 JBOSS 7 中部署 Struts 2 项目

java - 根据屏幕大小更改播放器的速度

java - 编写无代理 AMQP 到 MQTT 适配器

.net - 可移植类库和.NET ConcurrentDictionary