fas*_*ava 2 java parallel-processing java-stream
我有以下代码
final String arr[] = {"A", "B", "C", "D"};
final List<String> list1 = new ArrayList<>();
final List<String> list2 = Arrays.asList(arr).parallelStream()
.peek(s -> list1.add(s + s))
.map(s -> s + s)
.collect(Collectors.toList());
System.out.println(list1);
System.out.println(list2);
Run Code Online (Sandbox Code Playgroud)
我得到以下结果:
[null, AA, DD, null]
[AA, BB, CC, DD]
Run Code Online (Sandbox Code Playgroud)
为什么有些元素null在list1 中显示?我知道我应该使用SynchronizedList带parallelStream,但null值是令我感到诧异.一旦你向列表中添加了一些应该设置插槽的东西,下一次执行就应该为它添加另一个值.
ArrayList是不是一个线程安全的集合,你尝试从众多线程更新它parallelStream,你看到的是resizing内部数组的结果ArrayList- 该操作也不是线程安全的,你首先增加数组然后将元素移动到它:可能是元素没有被移动,你试图访问它.
为了使它更加明确,调整发生在一个新的阵列与增大的尺寸创建-如果充满了这种新的阵列null小号只复制发生之后.
这将是不可预测的将会发生什么,只是不要依赖任何这些.
编辑
我不能将此作为评论发布,但这里有一些代码证明null可以看出:
List<Integer> result = IntStream.iterate(0, i -> i + 1)
.takeWhile(i -> {
String arr[] = { "A", "B", "C", "D", "E", "F", "G", "H", "R", "T" };
List<String> list = new ArrayList<>();
Arrays.stream(arr)
.parallel()
.peek(list::add)
.forEach(x -> {
});
if (list.contains(null)) {
System.out.println("It took " + i + " steps to see a null");
return false;
}
return true;
})
.boxed()
.collect(Collectors.toList());
Run Code Online (Sandbox Code Playgroud)