列出使用并行流设置空值

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 中显示?我知道我应该使用SynchronizedListparallelStream,但null值是令我感到诧异.一旦你向列表中添加了一些应该设置插槽的东西,下一次执行就应该为它添加另一个值.

Eug*_*ene 6

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)

  • 看到`null`值应该不足为奇,让数组在设置之前充满'null`值.+1 (3认同)