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
相关产品推荐
相关产品推荐

