gpt4 book ai didi

java - Java 8 流中的非干扰确切含义

转载 作者:塔克拉玛干 更新时间:2023-11-03 02:57:00 24 4
gpt4 key购买 nike

使用非并发数据结构源流的非干扰要求是否意味着我们不能在流管道执行期间更改数据结构的元素状态(除此之外我们不能改变源数据结构本身)? (问题一)

在关于 non-interference 的部分,在流包描述中,它说:“对于大多数数据源而言,防止干扰意味着确保数据源在流管道执行期间根本不被修改。”

这段话没有提到修改元素的状态?

例如,假设“shapes”是非线程安全集合(例如ArrayList),下面的代码是否被认为有干扰? (问题二)

shapes.stream() 
.filter(s -> s.getColor() == BLUE)
.forEach(s -> s.setColor(RED));

这个例子取自 reliable source (至少可以说),所以它应该是正确的。但是,如果我将 stream() 更改为 parallelStream(),它仍然是安全和正确的吗? (问题三)

另一方面,另一可靠来源Naftalin Maurice的“Mastering Lambdas”明确指出,通过管道操作改变元素的状态(值)确实是干扰。来自关于不干扰的部分(3.2.3):

“但流的规则禁止任何线程对流源进行任何修改,例如,包括更改元素的值,而不仅仅是管道操作。”

如果书中所说的是正确的,是否意味着我们不能使用 Stream API 来修改元素的状态(使用 forEach),而必须使用常规迭代器(或 for-each,或 Iterable.forEach)? (问题四)

最佳答案

有一类更大的函数叫做“有副作用的函数”。 JavaDoc 声明是正确和完整的:这里的干扰意味着修改可变源。另一种情况是有状态表达式:依赖于应用程序状态或更改此状态的表达式。您可以阅读 Parallelism Oracle 站点上的教程。

一般来说,你可以自己修改流元素,这不应该被称为“干扰”。请注意,如果流源多次生成相同的可变对象(例如,使用 Collections.nCopies(10, new MyMutableObject()).parallelStream()。虽然它确保相同流元素不会被多个线程同时处理,如果您的流两次生成相同的元素,您在 forEach 中修改它时肯定会遇到竞争条件,例如。

因此,虽然有状态表达式有时会产生异味,如果有无状态的替代方案,应谨慎使用并避免使用,但如果它们不干扰流源,则它们可能没问题。当需要无状态表达式时(例如,在 Stream.map 方法中),API 文档中会特别提及。在 forEach 文档中,只需要不干涉。

回到你的问题:

问题1:不可以改变元素状态,这不叫干扰(虽然叫statefullness)

问题 2:不,除非您的流源中有重复对象,否则它没有干扰)

问题 3:您可以在那里安全地使用 parallelStream()

问题4:不可以,这种情况下可以使用Stream API。

关于java - Java 8 流中的非干扰确切含义,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32837415/

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