Java 7:Fork / Join框架

有人能解释一下Fork / Join是什么吗?

Fork Join是一个新的框架,它具有更易于使用的API,用于并行,分而治之的算法。

假设您有一个长时间运行的任务,对于此实例,具有复杂的算法。 您可能希望分叉大型任务,现在可以处理这两项任务。 现在让我们说那两个任务仍然太大,你可以将每个任务分成两个任务(此时有四个)。

您将继续此操作,直到每个任务都处于可接受的大小并调用算法。 重要的是要知道每个任务的调用是并行完成的。 任务完成后,它将与分叉的其他任务结合并合并结果。

这将继续,直到所有任务都已加入并返回一个任务。

除了已经说过的内容之外,fork / join还利用工作窃取 – 用尽事情的线程可以从其他忙碌的线程中窃取任务。 这里有一个例子可以帮助您了解如何使用FJ:

public class SumCounter extends RecursiveTask { private final Node node; public SumCounter(Node node) { this.node = node; } @Override protected Long compute() { long sum = node.getValue(); List subTasks = new LinkedList<>(); for(Node child : node.getChildren()) { SumCounter task = new SumCounter(child); task.fork(); // run asynchronously subTasks.add(task); } for(SumCounter task : subTasks) { sum += task.join(); // wait for the result } return sum; } public static void main(String[] args) { Node root = getRootNode(); new ForkJoinPool().invoke(new SumCounter(root)); } } 

这是了解Fork和Join的非常好的资源:

分叉和加入:Java可以在无痛并行编程中使用Excel! 作者Julien Ponge

假设您有一系列需要处理的事物。 您有许multithreading可以获取此集合的子集并处理它们。 他们都同时执行此操作(fork部分),然后在返回之前等待最后一个完成(连接部分)。

我只需要花两分钱就可以简单地理解Fork / Join。

 What is Fork/Join? The fork/join framework is an implementation of the ExecutorService interface that helps you take advantage of multiple processors. It is designed for work that can be broken into smaller pieces recursively. The goal is to use all the available processing power to enhance the performance of your application. 
  • 这个框架对于分而治之的问题非常有用。 这种方法适用于可以递归划分并以较小规模计算的任务; 然后组合计算结果。
  • 该框架是ExecutorService接口的一个实现,它提供了一个易于使用的并发平台,以便利用多个处理器。

对此框架有用的术语

  • 分叉:将任务划分为较小的任务是分叉。
  • 加入:合并较小任务的结果即可加入

与任何ExecutorService实现一样,fork / join框架将任务分配给线程池中的工作线程。 fork / join框架是不同的,因为它使用了工作窃取算法 。 不用做的事情的工作线程可以从仍然忙碌的其他线程中窃取任务。

Fork / Join算法的设计如下:

  • 拆分任务
  • 分叉任务
  • 加入任务
  • 撰写结果
 doRecursiveTask(input){ if( task is small enough to handled by a thread){ compute the small task; if there is result to return, then do so }else{ divide the task ie, fork() into two parts call compute on first task, join on second task, combine both results and return } } 

什么是工作窃取算法?

Fork / Join框架中的每个工作线程都有一个工作队列,使用Deque实现。 每次创建新任务(或子任务)时,都会将其推送到自己队列的头部。 当任务完成任务并与尚未完成的另一个任务执行连接时,它会很智能。 线程从其队列的头部弹出一个新任务并开始执行而不是hibernate(为了等待另一个任务完成)。 实际上,如果线程的队列为空,则线程从属于另一个线程的队列的尾部弹出一个任务。 这只不过是一种偷工作的算法。 更多细节在这里