- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
引用Java's Fork/Join vs ExecutorService - when to use which? ,一个传统的线程池通常用于处理很多独立的请求;和一个 ForkJoinPool
用于处理连贯/递归任务,其中一个任务可能会产生另一个子任务并稍后加入。
那么,为什么 Java-8 的 parallelStream
使用 ForkJoinPool
默认情况下但不是传统的执行者?
在很多情况下,我们使用 forEach()
在 stream()
之后或 parallelStream()
然后提交一个功能接口(interface)作为参数。在我看来,这些任务是独立的,不是吗?
最佳答案
一件重要的事情是 ForkJoinPool
也可以执行“正常”任务(例如 Runnable
、 Callable
),因此它不仅仅用于递归创建的任务。
另一件(重要的)事情是 ForkJoinPool
有多个队列,每个工作线程一个,用于任务,其中普通执行器(例如 ThreadPoolExecutor
)只有一个。这对他们应该运行什么样的任务有很大影响。
普通 executor 必须执行的任务越小越多,将任务分配给 worker 的同步开销就越高。如果大部分任务都很小,worker 会经常访问内部任务队列,这会导致同步开销。
这里是ForkJoinPool
它的多个队列闪耀着光芒。每个worker只从自己的队列中取任务,大部分时间不需要通过阻塞来同步,如果为空,可以从另一个worker那里偷任务,但是从队列的另一端,这也很少会导致同步开销,因为工作窃取应该很少见。
现在这与并行流有什么关系?流框架旨在易于使用。当您想轻松地将某些任务拆分为许多并发任务时,应该使用并行流,其中所有任务都相当小而简单。这是ForkJoinPool
是合理的选择。它在大量较小的任务上提供了更好的性能,如果需要,它也可以处理更长的任务。
关于concurrency - 为什么parallelStream 使用的是ForkJoinPool,而不是普通的线程池?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61766068/
我是一名优秀的程序员,十分优秀!