Java的Fork / Join与ExecutorService

我刚读完这篇文章:Java-5 ThreadPoolExecutor比Java-7 ForkJoinPool有什么优势? 并觉得答案不够直。

你能用简单的语言和例子来解释一下,Java 7的Fork-Join框架和旧的解决方案之间有什么权衡

我也看到了谷歌的#1命中的话题Java技巧:当使用ForkJoinPool VS的ExecutorService从javaworld.com但是, 它谈论大多API差异的文章并没有回答标题问题...


分叉连接允许您轻松执行分割和征服作业,如果要在ExecutorService中执行作业,必须手动执行作业。 在实践中,ExecutorService通常用于同时处理许多独立的请求(又名事务),并在您想要加速一个连贯的工作时进行分叉连接。


分叉连接对于递归问题特别有用,其中任务涉及运行子任务并处理其结果。 (这通常被称为“分而治之”......但这并不能揭示基本特征。)

如果您尝试使用传统线程(例如,通过ExecutorService)解决像这样的递归问题,最终会遇到等待其他线程向其传递结果的线程。

另一方面,如果问题没有这些特征,那么使用fork-join并没有真正的好处。


这里有一个更详细的“Java技巧”文章:


Java 8在Executors中提供了更多的API

static ExecutorService  newWorkStealingPool()

使用所有可用的处理器创建工作线程池作为其目标并行级别。

随着此API的添加,Executor提供了不同类型的ExecutorService选项。

根据您的要求,您可以选择其中之一或者您可以查看ThreadPoolExecutor,它可以更好地控制有界任务队列大小, RejectedExecutionHandler机制。

  • static ExecutorService newFixedThreadPool(int nThreads)

    创建一个线程池,该线程池重用使用共享无界队列运行的固定数量的线程。

  • static ScheduledExecutorService newScheduledThreadPool(int corePoolSize)

    创建一个线程池,可以安排命令在给定延迟后运行,或定期执行。

  • static ExecutorService newCachedThreadPool(ThreadFactory threadFactory)

    创建一个线程池,根据需要创建新线程,但会在先前构建的线程可用时重用它,并在需要时使用提供的ThreadFactory创建新线程。

  • static ExecutorService newWorkStealingPool(int parallelism)

    创建一个线程池,该线程池维护足够的线程以支持给定的并行性级别,并可以使用多个队列来减少争用。

  • 这些API中的每一个都旨在满足您应用程序的相应业务需求。 使用哪一个将取决于您的使用案例要求。

    例如

  • 如果您想按照到达顺序处理所有提交的任务,只需使用newFixedThreadPool(1)

  • 如果要优化递归任务的大计算性能,请使用ForkJoinPoolnewWorkStealingPool

  • 如果要定期或在将来某个时间执行某些任务,请使用newScheduledThreadPool

  • 看一看PeterLawrey关于ExecutorService用例的更好的文章。

    相关的SE问题:

    java分叉/加入池,ExecutorService和CountDownLatch

    链接地址: http://www.djcxy.com/p/92049.html

    上一篇: Java's Fork/Join vs ExecutorService

    下一篇: When one worker thread fails, how to abort remaining workers?