在Java 8中,有两种启动异步计算的方法 - CompletableFuture
和ForkJoinTask
。它们看起来都非常相似 - CompletableFuture
的内部类甚至扩展ForkJoinTask
。
是否有理由使用其中一个?
我可以看到的一个关键区别是,CompletableFuture.join
方法只会阻止,直到将来完成(waitingGet
仅使用ManagedBlocker
旋转),而ForkJoinTask.join
可以从队列中窃取工作,以帮助您完成加入的任务。
是否有益于其中一种?
答案 0 :(得分:4)
它们是两个不同的东西,ForkJoinTask
是一个可以提交给ForkJoinPool
的任务,CompletableFuture
是一个可以与任何Executor
和执行者一起使用的承诺不需要是ForkJoinPool
,
但是,如果您没有指定任何内容,那么普通ForkJoinPool
是默认值,例如:
CompletableFuture.supplyAsync(()-> supplier);
如果您没有通过ForkJoinPool
,则使用Executor
。还有另一个overload
需要Executor
。
CompletableFuture.supplyAsync(()-> supplier,executor);
Async
,static
中的CompletableFuture
类扩展了ForkJoinTask<Void>
,但它并不需要是ForkJoinTask
,来自Async
/ **基类可以作为FJ或普通的Runnable * /
abstract static class Async extends ForkJoinTask<Void>
implements Runnable, AsynchronousCompletionTask
它还可以是Runnable
和AsynchronousCompletionTask
旁边注意:ForkJoinTask
,ForkJoinPool
,ForkJoin...
类已添加到1.7而不是1.8
答案 1 :(得分:2)
我说当你有一个大任务并希望将它拆分为在几个子任务中并行运行时,更推荐ForkJoinTask
。 ForkJoin
框架使用工作窃取算法,该算法将有效地使用线程。另一方面,CompletableFutures
更适合于Reactive编程模型,您可以在其中以同步或异步方式创建执行管道,并通过使用Executor Service的线程池更好地控制线程。