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

关于ParallelStream列表的潜在竞争条件的问题

王飞英
2023-03-14

我遇到了这段代码,它使用Java流,特别是parallelStream(),以便从oracle数据库收集一些数据。见下文,在这种情况下:

  • 范围=一些输入Id列表
ForkJoinPool threadPool = new ForkJoinPool(Math.min(Runtime.getRuntime().availableProcessors(), parallelism));

try {
    Optional<C> res = threadPool.submit(new Callable<Optional<C>>() {
        @Override
        public Optional<C> call() throws Exception {
            return splitByLimit(range, rangeLimit).parallelStream()
               .map(rangeLimitedFunction::apply)
               .reduce((list, items) -> {
                   list.addAll(items);
                   return list;
               });
        }
    }).get();

据我所知,这是如何工作的:

  1. 将范围拆分为1000个块以输入函数
  2. 处理线程中的每个块以返回一些结果
  3. 将结果汇总到POJO列表中

我的问题是试图减少到单个列表中所带来的潜在竞争条件。这些线程中的许多是否有可能尝试将内容添加到结果列表中并可能损坏数据?

共有1个答案

傅英喆
2023-03-14

这在很大程度上取决于在本例中使用的List的实现。

这就是说,使用flatMap和收集器可以更好地利用Java并行流的线程安全性,避免非线程安全列表实现的潜在陷阱。

也就是说,并行流并没有为IO操作提供太多好处。它们针对处理器繁重的操作,通常只有在超过15000(IIRC)个操作(即流迭代次数乘以cpu繁重的流操作)时才有回报,这是一种罕见的情况。

 类似资料:
  • 我们正在对网络套接字使用阻塞系统I/O调用。我们想要的行为是当对套接字调用时,阻塞调用需要返回并抛出一个异常(引用), 看看OpenJDK,这就是它的实现方式。它使用用户信号唤醒阻塞线程。相应的信号处理程序是no-op。在阻塞调用之前,它注册可能被阻塞的线程。当关闭文件描述符时,关闭线程向阻塞的I/O线程发送信号,这导致阻塞调用返回。 不过,我还是认为下面的代码块源代码中存在一个潜在的竞争条件:

  • 我已经编写了一个计时器,它将测量任何多线程应用程序中特定代码的性能。在下面的计时器中,它还将用x毫秒的调用次数填充映射。我将使用这个图作为我的直方图的一部分来做进一步的分析,比如调用的百分比花费了这么多毫秒等等。 例如,这是我将使用上面的计时器类来衡量多线程应用程序中特定代码的性能的方式: 现在我的问题是,如果你看一下getDuration方法,我也会在我的地图中填充一些信息,比如花了x毫秒的调用

  • 9.1. 竞争条件 在一个线性(就是说只有一个goroutine的)的程序中,程序的执行顺序只由程序的逻辑来决定。例如,我们有一段语句序列,第一个在第二个之前(废话),以此类推。在有两个或更多goroutine的程序中,每一个goroutine内的语句也是按照既定的顺序去执行的,但是一般情况下我们没法去知道分别位于两个goroutine的事件x和y的执行顺序,x是在y之前还是之后还是同时发生是没法

  • 问题内容: (注意:这是针对MS SQL Server的) 假设您有一个具有主键标识列和CODE列的表ABC。我们希望此处的每一行都有一个唯一的,顺序生成的代码(基于一些典型的校验位公式)。 假设您有另一个仅具有一行的表DEF,该表存储下一个可用的CODE(想象一个简单的自动编号)。 我知道像下面这样的逻辑将呈现一种竞争状态,其中两个用户可能最终得到相同的CODE: 我知道,两个用户可能会卡在步骤

  • 9.6. 竞争条件检测 即使我们小心到不能再小心,但在并发程序中犯错还是太容易了。幸运的是,Go的runtime和工具链为我们装备了一个复杂但好用的动态分析工具,竞争检查器(the race detector)。 只要在go build,go run或者go test命令后面加上-race的flag,就会使编译器创建一个你的应用的“修改”版或者一个附带了能够记录所有运行期对共享变量访问工具的tes

  • 问题内容: 我有一个订单队列,可通过存储过程由多个订单处理器访问。每个处理器传递一个唯一的ID,该ID用于锁定接下来的20个订单以供自己使用。然后,存储过程将这些记录返回给要处理的订单处理器。 在某些情况下, 多个处理器能够检索相同的“ OrderTable”记录 ,此时它们将尝试同时对其进行操作。这最终会导致在该过程的后期引发错误。 我的下一个动作是允许每个处理器抓住所有可用的订单,然后对处理器