有人能解释一下Fork / Join是什么吗?
答案 0 :(得分:8)
Fork Join是一个新的框架,它具有更易于使用的API,可用于并行,分而治之的算法。
假设您有一个长时间运行的任务,对于此实例,它具有复杂的算法。您可能希望分叉大型任务,现在可以处理这两项任务。现在让我们说这两个任务仍然太大,你可以将每个任务分成两个任务(此时有四个)。
您将继续此操作,直到每个任务都达到可接受的大小并调用算法。重要的是要知道每个任务的调用是并行完成的。任务完成后,它将与分叉的其他任务结合并合并结果。
这将继续,直到所有任务都已加入并返回一个任务。
答案 1 :(得分:4)
检查这些链接 -
http://www.artima.com/forums/flat.jsp?forum=276&thread=219155
http://lambda-the-ultimate.org/node/3521
http://www.ibm.com/developerworks/java/library/j-jtp11137.html
答案 2 :(得分:3)
除了已经说过的内容之外,fork / join还利用工作窃取 - 忙碌的线程可以从其他忙碌的线程中窃取任务。这里有一个例子可以帮助您了解如何使用FJ:
public class SumCounter extends RecursiveTask<Long> {
private final Node node;
public SumCounter(Node node) {
this.node = node;
}
@Override
protected Long compute() {
long sum = node.getValue();
List<ValueSumCounter> 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));
}
}
答案 3 :(得分:3)
这是理解Fork和Join的非常好的资源:
Fork and Join: Java Can Excel at Painless Parallel Programming Too! 作者Julien Ponge
答案 4 :(得分:2)
假设您有一系列需要处理的事情。您有许多线程可以获取此集合的子集并进行处理。他们都同时执行此操作(fork部分),然后在返回之前等待最后一个完成(连接部分)。
答案 5 :(得分:1)
让我用两分钱来简单地理解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实现一样,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 i.e, fork() into two parts call compute on first task, join on second task, combine both results and return } }
什么是工作窃取算法?
Fork / Join框架中的每个工作线程都有一个工作队列 使用Deque实现。每次新任务(或子任务)都是 创建后,它被推送到自己队列的头部。当一个任务 完成一项任务并与另一项未执行的任务执行连接 完成了,它很聪明。该线程从中弹出一个新任务 它的队列头并开始执行而不是睡觉(按顺序 等待另一个任务完成)。实际上,如果是队列的话 线程为空,然后线程从尾部弹出一个任务 队列属于另一个线程。这只不过是偷工作 算法。 More detail is here
答案 6 :(得分:0)
我将回答什么是Fork Join并行性。这是广泛用于许多系统以实现并发性的并行设计模式之一。我将通过一个示例来解释这种设计模式。
例如,假设我们有执行任务序列的程序:
A-> B-> C->D。这里A,B,C,D是任务。
因此,此程序执行总共需要8 + 4 + 6 + 7 = 25秒。
现在您发现任务A,B,C是独立的,而D则取决于A,B,C任务的结果。现在您可能会感觉到,不必等待A完成,我们可以同时开始执行B。与任务C相同 可以同时与A和B启动任务。您可以做的是:您可以通过主线程调用3个新线程,并将它们分配给A,B,C任务,并等待结果开始执行任务D。如果计算机具有多个核心,则这些线程可以并行运行。
现在程序的执行时间为:
max(time_taken_A,_B,_C) + time_taken_D + threading_overhead_time
几乎等于= 8 + 7 + k = 15 + k;
在fork连接并行性中,只有这些任务是独立的,我们才可以用新线程卸载任务。否则我们将面临比赛条件。如果您有一个程序正在等待一个任务在等待另一个任务的执行,但是这不依赖于其结果,则可以使用fork join parallelism用新线程来分担这两个任务,从而提高性能。但是,请始终考虑线程开销。如果您的任务权重很轻,那么使用这些并行模式会由于线程创建和上下文切换开销而降低性能。