java Fork/Join有关堆栈使用情况的说明

ben*_*nyl 18 java concurrency fork-join java-7

我读到了Java 7中引入的Fork/Join框架的实现,我只是想检查一下我是否理解了魔法是如何工作的.

据我所知,当一个线程分叉时,它会在其队列中创建子任务(其他线程可能会或可能不会被窃取).当线程尝试"加入"时,它实际上检查其队列中的现有任务,然后递归执行它们,这意味着对于任何"连接"操作 - 将在线程调用堆栈中添加2个帧(一个用于连接,一个用于连接)对于新的任务调用).

据我所知,JVM不支持尾调用优化(在这种情况下可以用于删除连接方法堆栈帧)我相信在执行带有大量分支和连接的复杂操作时,线程可能会抛出StackOverflowError.

我是对的还是他们找到了一些防止它的好方法?

编辑

这是一个帮助澄清问题的场景:说(为简单起见)我们在forkjoin池中只有一个线程.在某个时间点 - 线程分叉然后调用join.在join方法中,线程发现它可以执行分叉任务(因为它在队列中找到),因此它调用下一个任务.此任务依次分叉然后调用join - 因此在执行join方法时,线程将在其队列中找到分叉任务(如前所述)并调用它.在该阶段,调用堆栈将至少包含两个连接和两个任务的帧.

正如您所看到的,fork join框架转换为普通递归.因为java不支持尾调用优化 - java中的每次递归都会导致StackOverflowError它变得足够深.

我的问题是 - fork/join框架的实现者是否找到了防止这种情况的一些很酷的方法.

Joh*_*int 8

不幸的是,就线程递归堆栈而言,没有任何神奇的事情发生.如果您的初始任务分叉/分裂并且没有合理的分辨率点,那么您将遇到StackOverflowErrors.

您可以理解为什么JavaDoc上的教程将每个子任务分成两半.