当前位置: 首页 > 知识库问答 >
问题:

reduce操作中并行流的同步问题

糜俊彦
2023-03-14

我正在尝试使用并行流连接字符串。

StringBuffer concat = Arrays.stream(grades)
        .parallel()
        .reduce(
                new StringBuffer(),
                (sb, s) -> sb.append(s),
                (sb1, sb2) -> sb1.append(sb2)
        );

我在下面的代码中也发现了同样的问题。

List<Integer> ages = people
            .stream()
            .parallel()
            .reduce(
                Collections.synchronizedList(new ArrayList<>()),
                (list, p) -> { list.add(p.getAge()); return list; },
                (list1, list2) -> { list1.addAll(list2) ; return list1; }
            );

在这里,我还使用了一个同步集合,所有的方法都是线程安全的。

我在Java文档中看到了这个

int sum = numbers.stream().reduce(0, (x,y) -> x+y);   or:

int sum = numbers.stream().reduce(0, Integer::sum);   These reduction operations can run safely in parallel with almost no
int sum = numbers.parallelStream().reduce(0, Integer::sum);   Reduction parallellizes well because the implementation can operate on

我是不是漏掉了什么?使用线程安全的数据结构还不够吗?

共有1个答案

杜经艺
2023-03-14

当您执行新建StringBuffer()时,您正在创建对单个缓冲区的引用。当您执行.parallel()时,两个并行流都将传递这个引用,从而在同一个可变缓冲区上操作。空缓冲区首先用“B”缩小,然后用“A”缩小,然后缩小到自身,产生“baba”。

对于使用可变结构(如StringBuffers)进行类似的操作,可以尝试.collect():

StringBuffer concat = Arrays.stream(grades).parallel().collect(
    () -> new StringBuffer(),
    (sb, s) -> sb.append(s),
    (sb1, sb2) -> sb1.append(sb2));
 类似资料:
  • 将使用最后两个元素(和),而不考虑一旦遇到就知道产品了。

  • 本章主要内容 等待事件 带有期望的等待一次性事件 在限定时间内等待 使用同步操作简化代码 在上一章中,我们看到各种在线程间保护共享数据的方法。当你不仅想要保护数据,还想对单独的线程进行同步。例如,在第一个线程完成前,可能需要等待另一个线程执行完成。通常情况下,线程会等待一个特定事件的发生,或者等待某一条件达成(为true)。这可能需要定期检查“任务完成”标识,或将类似的东西放到共享数据中,但这与理

  • 更多面试题总结请看:【面试题】技术面试题汇总 基本概念 临界资源:一次仅允许一个进程使用的共享资源,也就是互斥资源 临界区:程序中访问临界资源的那段代码,也称危险区、敏感区 互斥:多个程序片段,同一时刻仅有一个能进入临界区 同步:若干程序片断运行必须严格按照规定的某种先后次序来运行。同步是一种更复杂的互斥:互斥不会限制程序对资源的访问顺序,即访问是无序的;而同步必须要按照某种次序来运行 临界区管理

  • 我在读关于无国籍状态的文章时,在Doc中看到了这句话: 如果流操作的行为参数是有状态的,则流管道结果可能是不确定的或不正确的。有状态的lambda(或实现适当功能接口的其他对象)的结果取决于流管道执行过程中可能改变的任何状态。 现在,如果我有一个字符串列表(),然后尝试使用并行流以以下方式从其中删除重复的字符串: 这段代码是否有问题,因为并行流会分割输入,并且在一个块中的distinct不一定意味

  • 我试图理解方法是如何精确地处理并行流的,我不理解为什么下面的代码不返回这些字符串的串联。 代码如下: 该代码仅适用于顺序流,但对于并行流,它不会返回串联。每次输出都不同。有人能解释一下那里发生了什么事吗?

  • 本文向大家介绍async/await让异步操作同步执行的方法详解,包括了async/await让异步操作同步执行的方法详解的使用技巧和注意事项,需要的朋友参考一下 一.前言 我们经常会遇到这样的麻烦事,多个函数按顺序执行,返回结果却不是我们预期的顺序,原因一般是由于异步操作引起的,所以呢,我们需要一种解决方案来处理这种问题,从而使得异步操作按照同步的方式来执行,这样我们就可以控制异步操作输出结果的