当前位置: 首页 > 知识库问答 >
问题:

非递归任务的Java ForkJoinPool,偷工减料行得通吗?

夹谷山
2023-03-14

我想通过以下方法将<code>Runnable<code>任务提交到ForkJoinPool:

forkJoinPool.submit(Runnable task)

注意,我使用JDK 7。

在引擎盖下,它们被转换为ForkJoinTask对象。我知道ForkJoinPool在任务递归地分成较小的任务时是有效的。

问题:

如果没有递归,工作窃取在ForkJoinPool中仍然有效吗?

在这种情况下值得吗?

更新1:任务小,可以不平衡。即使对于严格相等的任务,如上下文切换、线程调度、暂停、页面丢失等。成为导致不平衡的障碍。

更新2:Doug Lea在并发JSR-166兴趣小组中写道,对此给出了提示:

当所有任务都是异步的并提交到池而不是分叉时,这也大大提高了吞吐量,这成为构建执行组件框架以及许多可能使用ThreadPoolExecutor的普通服务的合理方法。

我认为,当涉及到相当小的CPU密集型任务时,ForkJoinPool是要走的路,这要归功于这种优化。重点是这些任务已经很小,不需要递归分解。偷工是有效的,不管是大任务还是小任务——任务可以被另一个自由工人从繁忙工人的Deque尾巴上抓取。

更新3:ForkJoinPool的可扩展性-乒乓球Akka团队的基准测试显示了巨大的结果。

尽管如此,要更有效地应用ForkJoinPool,需要进行性能调优。

共有1个答案

孙光临
2023-03-14

ForkJoinpool源代码有一个很好的部分,称为“实现概述”,阅读以获得终极真理。下面的解释是我对JDK 8u40的理解。

从第一天起,< code>ForkJoinPool就为每个工作线程准备了一个工作队列(让我们称之为“工作队列”)。分叉的任务被推入本地工作队列,准备好被工作线程再次弹出并执行——换句话说,从工作线程的角度看,它就像一个堆栈。当一个工作者耗尽它的工作者队列时,它会四处寻找并试图从其他工作者队列中窃取任务。那就是“偷工减料”。

现在,在(IIRC)JDK 7u12之前,ForkJoinPool有一个单一的全局提交队列。当工作线程用完本地任务以及要窃取的任务时,它们会到达那里并尝试查看外部工作是否可用。在这种设计中,与常规的<code>ThreadPoolExecutor

在那之后,它发生了重大变化。在这个提交队列被确定为严重的性能瓶颈后,Doug Lea等人。也对提交队列进行了条带化。事后看来,这是一个显而易见的想法:您可以重用大多数可用于工作队列的机制。您甚至可以松散地将这些提交队列分配给每个工作线程。现在,外部提交进入其中一个提交队列。然后,没有工作可供咀嚼的工作人员可以首先查看与特定工作人员相关的提交队列,然后四处走动查看其他人的提交队列。人们也可以称之为“工作窃取”。

我已经看到许多工作负载从中受益。即使对于普通的非递归任务,ForkJoinPool的这种特殊设计优势在很久以前就被认识到了。conmonce-interest@的许多用户要求一个没有所有ForkJoinpool奥秘的简单工作窃取执行程序。这就是为什么我们在JDK 8中有Executors.newWorkStealingPool()的原因之一——目前委托给ForkJoinpool,但为了提供更简单的实现而开放。

 类似资料:
  • 问题内容: 我想通过一种方法将任务提交到ForkJoinPool中: 注意,我使用的是JDK 7。 在后台,它们被转换为ForkJoinTask对象。我知道,当将任务递归拆分为较小的任务时,ForkJoinPool是有效的。 题: 如果没有递归,偷窃工作是否仍可以在ForkJoinPool中进行? 在这种情况下值得吗? 更新1: 任务很小,可以不平衡。即使对于严格相等的任务,诸如上下文切换,线程调

  • 作为考试准备的一部分,我一直在努力解决问题,我想我需要你的帮助。我需要写一个布尔方法,需要整数数组(正和负),并返回true,如果数组可以被拆分为两个相等的组,每个组的数字的量等于另一组。对于示例,对于这个数组: 该方法将返回true,因为-3514=12-913。 对于此阵列: 该方法将返回false,因为即使-3 5 14 -12 = -9 13,等式每边的数字量也不相等。 对于阵列: 该方法

  • 根据手册中的组件页面,根据本论坛帖子,将在2019年6月为第14版的Vaadin Flowpromise提供一个合适的菜单栏小部件。 在此之前,该页面建议使用和在第12版中安装菜单栏。 梅努巴 计划在瓦丁14号。当前可通过组合选择(V12)和上下文菜单(V12)进行设置 (a) 我在版本12Javadoc中找不到或。 (b) 有人可以分享一个示例实现吗?

  • 问题内容: 我正在寻找一种与作品一样的非递归步行方式。但是我需要以相同的方式退货。任何想法? 先感谢您。 问题答案:

  • 我有以下问题: 编写一个递归静态方法isSubstring,签名如下- 获取两个字符串-s1、s2,如果s2是s1的子字符串,则返回true。 该方法应该是递归的,完全不使用迭代。也可以使用您编写的任何其他方法(如果您编写的话)。 正确的答案不会改变方法类型签名/注释(即使通过重载也不会)。 您只能在解决方案中使用以下方法: 公共字符字符(int i) 公共int长度() 公共字符串子字符串(in

  • 通常为二叉树定义顺序。让我们假设顺序对于(普通)树是“扩展”的。如果树是单个节点,则该节点是树的顺序遍历。如果树T是具有T1,T2,…,的树。。。,Tk子树和r作为根,然后按T1的顺序,然后按r的顺序,然后按T2,T3,…,的顺序遍历。。,Tk是T的顺序遍历。 T以左子右同级表示形式给出。C中节点的数据结构为: 树用指向根的指针表示。根不能有正确的同级<问题是要找到一种算法来按顺序遍历树。不允许递