サンプル (テイラー展開でπを求める)
package com.mycompany.sandbox;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.RecursiveTask;
public class ForkJoinExam {
public static void main(String[] args) {
ForkJoinPool forkjoin = new ForkJoinPool();
System.out.println(forkjoin.invoke(new TaylorPi()));
}
}
class TaylorPi extends RecursiveTask<Double> {
private List<Long> data;
public TaylorPi() {
data = new ArrayList<>();
for (long l = 0L; l < 10_000_000L; l++) {
data.add(l);
}
}
public TaylorPi(List<Long> data) {
this.data = data;
}
@Override
protected Double compute() {
if (data.size() == 1) {
// データが短ければ自分で処理する
long l = data.get(0);
return 4.0 / (double)(((l & 1) == 0 ? 1L : -1L) * (2L * l + 1L));
}
// データを分割して、並列実行する
int i = data.size() / 2;
// 前半部分は別スレッドで実行
TaylorPi task1 = new TaylorPi(data.subList(0, i));
task1.fork();
// 後半部分は逐次実行し、前半部分の終了を待つ
TaylorPi task2 = new TaylorPi(data.subList(i, data.size()));
return task2.compute() + task1.join();
}
}
3.1415925535897915
テイラー展開ならこれくらいが限界かな。あと、これくらいなら fork-join しないほうが速い
Double を返すタスク | RecursiveTask?<Double> |
処理結果を返さないタスク | RecursiveAction? |
同期呼び出し | Double | ForkJoinPool?#invoke(RecursiveTask?<Double>) |
非同期呼び出し | Future<Double> | ForkJoinPool?#submit(RecursiveTask?<Double>) |
非同期呼び出し(突き放し実行) | void | ForkJoinPool?#execute() |