Fork-Join模式

什么是Fork-Join

“分治”问题可以很容易地通过Callable线程的Executor接口来解决。通过为每个任务实例化一 个Callable实例,并在ExecutorService类中汇总计算结果来得出最终结果可以实现这一目的。那么自然而然想到的问题就是,如果这接口已经做得不错了,我们为什么还需要Java 7的其他框架?
使用ExecutorServiceCallable的主要问题是,Callable实例在本质上是阻塞的。一旦一个Callable实例开始执行,其他所有Callable都会被阻塞。由于队列后面的Callable实例在前一实例未执行完成的时候不会被执行,因此许多资源无法得到利用。Fork-Join框架被引入来解决这一并行问题,而Executor解决的是并发问题(译者注:并发和并行的区别就是一个处理器同时处理多个任务和多个处理器或者是多核的处理器同时处理多个不同的任务)。
Fork-Join模式,分而治之,然后合并结果,这么一种编程模式。(注:Fork-Join是一个单机框架,类似的分布式的框架有Hadoop这类的,它们的计算模型是MapReduce,体现了和Fork-Join一样的思想-分而治之。)
Fork-Join框架是一个”多核友好的、轻量级并行框架”,它支持并行编程风格,将问题递归拆分成多个更小片断,以并行和调配的方式解决。Fork-join融合了分而治之技术;获取问题后,递归地将它分成多个子问题,直到每个子问题都足够小,以至于可以高效地串行地解决它们。递归的过程将会把问题分成两个或者多个子问题,然后把这些问题放入队列中等待处理(fork步骤),接下来等待所有子问题的结果(join步骤),把多个结果合并到一起。
Fork-Join模式有自己的适用范围。如果一个应用能被分解成多个子任务,并且组合多个子任务的结果就能够获得最终的答案,那么这个应用就适合用Fork-Join模式来解决。
一个Fork-Join模式的示意图,位于图上部的Task依赖于位于其下的Task的执行,只有当所有的子任务都完成之后,调用者才能获得Task 0的返回结果。如下图。


Fork-Join模式能够解决很多种类的并行问题。通过使用Doug Lea提供的Fork-Join框架,软件开发人员只需要关注任务的划分和中间结果的组合就能充分利用并行平台的优良性能。其他和并行相关的诸多难于处理的问题,例如负载平衡、同步等,都可以由框架采用统一的方式解决。这样,我们就能够轻松地获得并行的好处而避免了并行编程的困难且容易出错的缺点。

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×