分叉/联接框架如何比线程池更好?
与在开始时简单地将大任务拆分为N个子任务,将它们发送到缓存的线程池(来自执行器)并等待每个任务完成相比,使用新的fork/join框架有什么好处?我看不出使用fork/join抽象如何简化问题,或者使解决方案比我们多年来一直拥有的更有效。
例如,教程示例中的并行模糊算法可以按如下方式实现:
public class Blur implements Runnable {
private int[] mSource;
private int mStart;
private int mLength;
private int[] mDestination;
private int mBlurWidth = 15; // Processing window size, should be odd.
public ForkBlur(int[] src, int start, int length, int[] dst) {
mSource = src;
mStart = start;
mLength = length;
mDestination = dst;
}
public void run() {
computeDirectly();
}
protected void computeDirectly() {
// As in the example, omitted for brevity
}
}
在开始时拆分并将任务发送到线程池:
// source image pixels are in src
// destination image pixels are in dst
// threadPool is a (cached) thread pool
int maxSize = 100000; // analogous to F-J's "sThreshold"
List<Future> futures = new ArrayList<Future>();
// Send stuff to thread pool:
for (int i = 0; i < src.length; i+= maxSize) {
int size = Math.min(maxSize, src.length - i);
ForkBlur task = new ForkBlur(src, i, size, dst);
Future f = threadPool.submit(task);
futures.add(f);
}
// Wait for all sent tasks to complete:
for (Future future : futures) {
future.get();
}
// Done!
这些任务将转到线程池的队列,当工作线程变为可用时,将从该队列中执行这些任务。只要拆分足够精细(以避免特别等待最后一个任务),并且线程池具有足够(至少N个处理器)线程,所有处理器都在全速工作,直到整个计算完成。
我错过了什么吗?使用分叉/连接框架的附加价值是什么?