gpt4 book ai didi

java - Collection.parallelStream() 是否暗示发生在关系之前?

转载 作者:搜寻专家 更新时间:2023-10-30 23:01:20 26 4
gpt4 key购买 nike

考虑这个(完全人为的)Java 代码:

final List<Integer> s = Arrays.asList(1, 2, 3);
final int[] a = new int[1];
a[0] = 100;
s.parallelStream().forEach(i -> {
synchronized (a) {
a[0] += i;
}
});
System.out.println(a[0]);

这段代码能保证输出“106”吗?

似乎不是,除非有一个发生在之前的关系由parallelStream()建立, 通过它我们可以确定第一个访问 a[0]在 lambda 中会看到 100而不是零(根据我对 Java 内存模型的理解)。

但是Collection.parallelStream()没有记录建立这种关系...

完成 parallelStream() 可以问同样的问题方法调用。

那么我是不是遗漏了什么,或者为了正确性,上面的代码是否需要看起来像这样:

final List<Integer> s = Arrays.asList(1, 2, 3);
final int[] a = new int[1];
synchronized (a) {
a[0] = 100;
}
s.parallelStream().forEach(i -> {
synchronized (a) {
a[0] += i;
}
});
synchronized (a) {
System.out.println(a[0]);
}

或者... parallelStream()实际上提供了这些happens-before 关系,而这只是缺少一些文档的问题?

我问是因为从 API 设计的角度来看,这似乎(至少对我而言)是合乎逻辑的事情......类似于 Thread.start()

最佳答案

您真的应该避免在管道“外部”使用变量。即使你让它正常工作,性能也可能会受到影响。 JDK 中内置了很多工具来实现这一点。例如,您的用例可能更安全,例如:

Integer reduce = IntStream.of(1, 2, 3)
.parallel()
.reduce(100, (accumulator, element) -> accumulator + element);

关于java - Collection.parallelStream() 是否暗示发生在关系之前?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53906027/

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