(); final List l-6ren">
gpt4 book ai didi

java - 使用并行流列表设置空值

转载 作者:行者123 更新时间:2023-12-02 06:09:23 24 4
gpt4 key购买 nike

我有以下代码

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);

我得到以下结果:

[null, AA, DD, null]
[AA, BB, CC, DD]

为什么 list1 中某些元素显示 null?我知道我应该将 SynchronizedListparallelStream 一起使用,但 null 值令我惊讶。一旦您将某些内容添加到列表中,就应该设置该插槽,并且下一次执行应该向其中添加另一个值。

最佳答案

ArrayList 不是一个线程安全的集合,并且您尝试使用 parallelStream 从多个线程更新它,您看到的是调整大小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());

关于java - 使用并行流列表设置空值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52861367/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com