使用parallelStream处理列表时如何让输出结果与原列表顺序一致
问题原因
你现在的写法存在两个核心问题:
ArrayList是非线程安全容器,多线程并行调用add方法会出现数据丢失、下标越界、元素重复等异常问题parallelStream().forEach()不保证元素处理顺序,就算容器线程安全,最终输出的元素顺序也和输入顺序无法匹配
解决方案
直接使用map做元素转换,配合Collectors.toList()完成结果收集即可,JDK自带的收集器会自动保证有序输入流的输出顺序和输入一致,且无线程安全问题。
修正后的代码如下:
import java.util.stream.Collectors; public List<XYZResponse> process(List<String> inputs) { return inputs.parallelStream() // 并行执行元素转换逻辑 .map(this::processStringInput) // 按原始输入顺序组装结果列表 .collect(Collectors.toList()); } private XYZResponse processStringInput(String input) { return new XYZResponse.Builder().resp(input).build(); }
补充说明
- 该方案的顺序保证前提是输入流本身是有序的,你这里输入是
List类型,天生有序,所以可以完全满足需求 - 并行处理过程中不同元素的执行顺序还是不确定的,但最终收集结果的时候会自动按照原始输入的顺序做拼接,不影响最终输出顺序
- 完全避免了手动操作共享容器的副作用,性能和稳定性都比手动加锁往列表塞元素的方案好很多
- 不推荐采用手动给
ArrayList的add操作加锁的实现,该方案会严重抵消并行流的性能优势,没有实际使用价值
内容的提问来源于stack exchange,提问作者whishky
相关产品推荐
相关产品推荐

