ForkJoinTask - join() 与 invoke()

ForkJoinTask - join() vs invoke()

Java 文档说 join() 的下一步:

Returns the result of the computation when it is done. This method differs from get() in that abnormal completion results in RuntimeException or Error, not ExecutionException, and that interrupts of the calling thread do not cause the method to abruptly return by throwing InterruptedException.

对于invoke()

Commences performing this task, awaits its completion if necessary, and returns its result, or throws an (unchecked) RuntimeException or Error if the underlying computation did so.

但即使阅读了文档,我也无法理解它们之间的区别。他们都在等待未来 return 结果,据我了解他们以不同的方式处理异常?

在 ForkJoinTask API 文档中,

The primary method for awaiting completion and extracting results of a task is join(), but there are several variants: The Future.get() methods support interruptible and/or timed waits for completion and report results using Future conventions. Method invoke() is semantically equivalent to fork(); join() but always attempts to begin execution in the current thread. The "quiet" forms of these methods do not extract results or report exceptions. These may be useful when a set of tasks are being executed, and you need to delay processing of results or exceptions until all complete. Method invokeAll (available in multiple versions) performs the most common form of parallel invocation: forking a set of tasks and joining them all.

简单来说,invoke() == fork();join();

fork() 本身是异步的,它将任务分成两个工作单元并将一个单元传递给另一个 ForkJoinTask,可用的 ForkJoinTask 数量由您的 ForkJoinPool 定义。并且,您将调用 join()/get() 等待它完成。

同时,invoke()是同步的,ForkJoinTask在主线程调用,立即阻塞主线程。如果您需要在 fork() 和 join() 之间执行某些操作,则无法执行。

所以我的建议是当您在 fork() 和 join() 之间无事可做并且您只需要纯多线程功能时使用 invoke()。如果您想在 ForkJoinTasks 之间进行高级连接或在两者之间执行某些操作,请使用 fork();join();

但请记住,这两种方法并不意味着您的任务可以拆分到另一个线程中。这取决于您机器中的物理线程数和为您的 ForkJoinPool 初始化的池数。