首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何使流减少线程安全?

如何使流减少线程安全?
EN

Stack Overflow用户
提问于 2021-02-22 15:01:25
回答 2查看 631关注 0票数 17

Java提供了一个通用的.reduce(identity, accumulator)方法。

从javadocs中可以很清楚地看出,累加器应该是一个无状态函数。

但是,我有一个关于identity对象的问题,即它应该是线程安全的吗?

让我们假设一个identity是一个java对象,而一个accumulator以一种非原子化的方式修改这个对象,例如accumulator查看identity's状态,然后决定如何精确地修改它的内部状态。很明显,可能会发生多个精简操作同时运行的情况。在这种情况下,出现了几个问题:

  • 这个减少操作应该是identity对象作用域中的原子操作吗?
  • 是否足以使identity对象不可变并在每个identity对象上返回一个新实例?
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2021-02-22 16:05:02

通常情况下,accumulator是一个英文单词,意思是:“如果你想要并行性的话,你会被完全冲洗”。它就在这个词里:积累--随着时间的推移而聚集。没有正确的方法,除非从一开始,并应用积累,直到你完成。

但是,java通过添加两个需求来解决这一问题:

  1. associativity.function.
  2. identity必须产生与(a X b) X c相同的结果,其中X是累加器(a X b) X c函数。ident X a必须等于a,其中ident是传递给reduce的标识,X是累加器函数。

让我们以函数(a, b) -> a + b和identity 0为例,如果您的目的是对一个列表进行求和,它就满足了这两个要求。

Java只需对任意项进行求和,然后对这些项的结果进行求和,就可以将其并行化。[1, 5, 9, 12]可以先将列表合并为两个,然后将这两个子列表分别交给线程进行求和,然后将每个线程提供的答案相加。--这意味着java将在流中的任意点开始多次积累,并将标识作为其累积的一部分应用于任意点(任意点),如果标识对象本身是可变的,则会带来迅速的问题。

基本上没有办法将可变的identity对象和java的reduce函数的概念结合起来。从根本上来说,它的设计并不是为了这样做的。

与求和示例相反:没有修改(a, b) -> a + b累加器中的a,也没有修改b;相反,它们被组合成一个新创建的第三个值,这就是您应该如何使用这个方法。

与来自某些其他语言的foldLeft形成对比,后者既不要求accumulatorFunction(ident, A)等于A,也不要求结合性,但根据定义,它根本不能并行化。foldLeft可以与可变状态一起使用。例如,下面是使用foldLeft (伪代码)求和的一个推动力:(请注意,这里new int[1]作为可变整数使用):

代码语言:javascript
运行
复制
int sum = stream.foldLeft(new int[1], (int[] a, int b) -> a[0] += b)[0];

这个概念(您的累加器函数的LHS总是相同的东西,即您的标识对象,在您沿着流移动时被修改为集成流中的每个值)是不兼容和java的缩减,而且据我所知,java没有(容易)的方法来对流进行这种操作。

这样就更糟了!‘线程安全’还不够好,它需要是不可变的。一旦它是不可变的,它就是线程安全的。

是否足以使identity对象不可变,并在每个reduce上返回一个新实例?

这不仅仅是“足够好”,这或多或少是使用reduce的唯一明智的方式。

票数 10
EN

Stack Overflow用户

发布于 2021-02-22 16:38:04

这是文档所涵盖的,但不是直接的,而是隐含的。

标识值必须是累加器函数的标识。这意味着对于所有的t,accumulator.apply(恒等式,t)等于t

就像您说的那样,一旦identity被修改,即使是以线程安全的方式,上面的规则也会被违反;因此无法保证预期的结果。

对于第二个问题,答案涉及得更多一些。您不必使identity不可变,只要没有人滥用它(通过修改它的内部状态)。当然,immutable在这方面有很大的帮助。

票数 8
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/66318158

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档