我正在阅读 Java ForkJoin 框架。不直接调用(例如)invoke()
的实现,而是实例化和调用,有什么额外的好处?当我们调用这 2 个方法时,到底会发生什么?ForkJoinTask
RecursiveTask
ForkJoinPool
pool.invoke(task)
invoke
从源头上看,如果recursiveTask.invoke
被调用,它会以托管线程池的方式调用它的exec
and 最终compute
。因此,为什么我们有成语更加令人困惑pool.invoke(task)
。
我写了一些简单的代码来测试性能差异,但我没有看到任何东西。也许测试代码是错误的?见下文:
public class MyForkJoinTask extends RecursiveAction {
private static int totalWorkInMillis = 20000;
protected static int sThreshold = 1000;
private int workInMillis;
public MyForkJoinTask(int work) {
this.workInMillis = work;
}
// Average pixels from source, write results into destination.
protected void computeDirectly() {
try {
ForkJoinTask<Object> objectForkJoinTask = new ForkJoinTask<>();
Thread.sleep(workInMillis);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
@Override
protected void compute() {
if (workInMillis < sThreshold) {
computeDirectly();
return;
}
int discountedWork = (int) (workInMillis * 0.9);
int split = discountedWork / 2;
invokeAll(new MyForkJoinTask(split),
new MyForkJoinTask(split));
}
public static void main(String[] args) throws Exception {
System.out.printf("Total work is %d in millis.%n", totalWorkInMillis);
System.out.printf("Threshold is %d in millis.%n", sThreshold);
int processors = Runtime.getRuntime().availableProcessors();
System.out.println(Integer.toString(processors) + " processor"
+ (processors != 1 ? "s are " : " is ")
+ "available");
MyForkJoinTask fb = new MyForkJoinTask(totalWorkInMillis);
ForkJoinPool pool = new ForkJoinPool();
long startTime = System.currentTimeMillis();
// These 2 seems no difference!
pool.invoke(fb);
// fb.compute();
long endTime = System.currentTimeMillis();
System.out.println("Took " + (endTime - startTime) +
" milliseconds.");
}
}