ForkJoinPoolにプール内の追加のスレッドを 1 つ与える限り、ExecutorService と同じくらい高速に実行されます。使用される 3 つのクラスは次のとおりです: Main、RunnableTask、および ForkJoinTask。16コアボックスで実行すると、プログラムは毎回次のように出力します: Executor Time: 5002 ForkJoin Time: 5002
メインクラス:
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ForkJoinPool;
public class Main {
public static void main(String[] args) throws InterruptedException {
runExecutor(80);
runForkJoin(80);
}
public static void runForkJoin(int size) {
ForkJoinPool fjp = new ForkJoinPool(17);
long start = System.currentTimeMillis();
fjp.invoke(new ForkJoinTask(size));
System.out.println("ForkJoin Time: "
+ (System.currentTimeMillis() - start));
fjp.shutdown();
}
public static void runExecutor(int size) throws InterruptedException {
ExecutorService exec = Executors.newFixedThreadPool(16);
CountDownLatch latch = new CountDownLatch(size);
long start = System.currentTimeMillis();
for (int i = 0; i < latch.getCount(); i++) {
exec.submit(new RunnableTask(latch));
}
latch.await();
System.out.println("Executor Time: "
+ (System.currentTimeMillis() - start));
exec.shutdown();
}
}
実行可能なクラス:
import java.util.concurrent.CountDownLatch;
public class RunnableTask implements Runnable {
private CountDownLatch latch;
public RunnableTask(CountDownLatch latch) {
this.latch = latch;
}
@Override
public void run() {
try {
Thread.sleep(1000);
latch.countDown();
} catch (Exception e) {
}
}
}
RecursiveTask クラス:
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.RecursiveTask;
public class ForkJoinTask extends RecursiveTask {
private List<RecursiveTask> tasks;
private int size;
public ForkJoinTask(int size) {
super();
this.tasks = new ArrayList<>();
this.size = size;
}
@Override
protected Object compute() {
for (int i = 0; i < size; i++) {
RecursiveTask task = new RecursiveTask() {
@Override
protected Object compute() {
try {
Thread.sleep(1000);
} catch (Exception e) {
}
return null;
}
};
task.fork();
tasks.add(task);
}
for (RecursiveTask task : tasks) {
task.join();
}
return null;
}
}