【发布时间】:2018-09-20 09:45:33
【问题描述】:
我想了解 Java fork-join pool 中处理任务的顺序。
到目前为止,我在文档中找到的唯一相关信息是关于一个名为“asyncMode”的参数,如果此池对分叉任务使用本地先进先出调度模式,则该参数为“true”从未加入”。
我对这句话的解释是,每个worker都有自己的任务队列;工作人员从自己队列的前面获取任务,或者如果他们自己的队列为空,则窃取其他工作人员队列的后面;如果 asyncMode 为 true(resp.false),worker 将新分叉的任务添加到他们自己队列的后面(resp.front)。
如果我的解释有误,请纠正我!
现在,这提出了几个问题:
1) 加入的分叉任务的顺序是什么?
我的猜测是,当一个任务被分叉时,它会被添加到工作人员的队列中,如我上面的解释中所述。现在,假设任务已加入...
如果调用 join 时任务尚未启动,调用 join 的工作人员会将任务拉出队列并立即开始工作。
如果在调用 join 时,任务已被另一个 worker 窃取,那么调用 join 的 worker 将同时处理其他任务(按照我在上面的解释中描述的获取任务的顺序),直到它加入的任务被偷走它的工人完成。
这个猜测是基于使用 print 语句编写简单的测试代码,并观察改变连接调用顺序影响任务处理顺序的方式。谁能告诉我我的猜测是否正确?
2) 外部提交的任务的顺序是什么?
根据the answer to this question,fork-join 池不使用外部队列。 (顺便说一下,我使用的是 Java 8。)
那么我是否理解当一个任务被外部提交时,该任务被添加到一个随机选择的工作队列中?
如果是,外部提交的任务是放在队列的后面还是前面?
最后,这取决于任务是调用pool.execute(task)提交还是调用pool.invoke(task)提交?这是否取决于调用 pool.execute(task) 或 pool.invoke(task) 的线程是外部线程还是此 fork-join 池中的线程?
【问题讨论】:
-
为什么不只是有一个look,源是开放的。
-
对于您问题的第 2 部分,您可能会在“Implementation overview”中找到一些见解
-
为什么你需要知道这个?订单未指定,因此可以随时更改。如果您转移到具有不同数量处理器的机器,它甚至会发生变化。如果您需要特定订单,请通过您自己的方式明确提供。
标签: java multithreading forkjoinpool