You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java并行流分块调用后端出现重复块问题求助

问题根源

你的问题出在单元测试里的ArgumentCaptor线程不安全,和业务代码本身无关。

当并行流同时发起多个API调用时,多个线程会同时访问同一个ArgumentCaptor实例。argumentCaptor.getValue()返回的是最后一次捕获到的参数,而非当前调用对应的参数——这就导致测试日志里出现重复分块的输出,甚至后续断言出错。尤其是当输入列表长度不是分块大小倍数时,最后一块的尺寸特殊,线程竞争更容易暴露这个问题。

解决方案

修改单元测试的thenAnswer逻辑,直接从当前调用的上下文获取参数,不要用ArgumentCaptor.getValue():

when(apiClient.getItemInfo(anyList()))
    .thenAnswer(invocationOnMock -> {
      // 直接获取当前调用的第一个参数,这是线程安全的
      List<String> currentChunk = invocationOnMock.getArgument(0);
      System.out.println(currentChunk.stream().collect(Collectors.joining(",")));
      Thread.currentThread().sleep(100);
      return currentChunk.stream().map(x -> ItemDto.builder().itemNumber(x).build()).toList();
    });

// 若需验证捕获的参数列表,仍可保留ArgumentCaptor,但不要在thenAnswer中使用
ArgumentCaptor<List<String>> argumentCaptor = ArgumentCaptor.forClass(List.class);
verify(apiClient, times(items.size() / 10 + 1)).getItemInfo(argumentCaptor.capture());

// 此处可安全获取所有捕获的参数
List<List<String>> allChunks = argumentCaptor.getAllValues();
补充说明
  • 业务代码的分块逻辑是正确的,并行流本身不会导致重复分块,问题完全来自测试中的线程不安全操作。
  • 换成CompletableFuture或ForkJoin后问题依旧,也是因为测试里的ArgumentCaptor用法错误,和并行执行的方式无关。

内容的提问来源于stack exchange,提问作者Bahram

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.17 20:21:06