Pra*_*Kvn 9 java parallel-processing java-stream
以下代码在完成并行处理后并未将所有元素放入目标列表中。这有什么原因吗?
public static void main(String[] args) {
List<Integer> source =new ArrayList<>();
List<Integer> destination = new ArrayList<>();
IntStream.range(0, 10000).forEach(element ->{
source.add(element);
});
//System.out.println(source.size());
source.parallelStream().forEach(c->{
destination.add(c);
});
System.out.println("Source Size:"+source.size());
System.out.println("destination size:"+destination.size());
}
Run Code Online (Sandbox Code Playgroud)
输出:源大小:10000 目标大小:4343
因为ArrayList不是线程安全的集合。使用类似线程安全的集合CopyOnWriteArrayList会使其正确但不一定有效。
使用 aCollector会更简单和正确。例如
source.parallelStream().collect(Collectors.toList())
Run Code Online (Sandbox Code Playgroud)
并行流的操作forEach是将元素从多个线程添加到非同步Collection(an ArrayList)。因此,该操作不是线程安全的,并且会产生意想不到的结果。
使用forEachOrdered()代替forEach()将确保 的所有元素都source List添加到destination List.
然而,正如另一个答案中提到的,使用是从 acollect(Collectors.toList())生成输出的正确方法。ListStream