JAvaマルチスレッドのパラレルフレームワークForkJoin
Java 7にForkJoinが新しく加わって、私は特に新しい字に惹かれやすい人で、好奇心の下で資料を調べました.それはJava 7が提供した原生のマルチスレッド並列処理フレームワークで、その基本思想は1つの大きなタスクを独立して実行するサブタスクに分割し、サブタスクの結果を最終的なresultに集約することです.私から見れば、彼の思想と迅速なソートアルゴリズムには異曲同工の妙がある.OK、まず私が大神が書いたdemoを参照してみましょう.
まず、RecursiveTaskクラスを継承していることがわかります.ForkJoinフレームワークを使用するには、まずForkJoinタスクを作成する必要があります.タスクでfork()とjoinを実行する操作メカニズムを提供します.通常、ForkjoinTaskクラスを直接継承するのではなく、サブクラスを直接継承する必要があります.
RecursiveAction:結果を返さない任 仕事
RecursiveTask:戻り値のあるタスクに使用します.ここで私が使っているのはRecursiveTaskで、ここのTは私たちが望んでいる結果のタイプです.また、computeメソッドを実装し、特定のタスクの詳細を定義する必要があります.
fork()はサブタスクを実行していることがわかります.
これはforkメソッドのソースコードです.
現在のタスクが実行中のプールでこのタスクを非同期で実行するか(適用される場合)、
そうでなければ
.これはjava apiの解釈で、明らかに私たちのタスクをワークキューに追加しました.forkメソッドは、私たちのタスクの結果を得て、結果を集約して私たちのタスクを定義します.累積です.
次にmainメソッドのコードを見てみましょう.ForkJoinPoolとは何ですか.ソースコードを見るとpublic class ForkJoinPool extends AbstractExecutorServiceが見つかります.そうです.ForkJoinPoolはforkjoinフレームワークのためにカスタマイズされたスレッドプールです.具体的な実装の詳細は見ないでください.submitを見るとよく知っているのではないでしょうか.そうです.私もそうです.この方法を見るとcallableインタフェースを思い出しました.実際には、私たちが推測したように、この2つの方法の役割は類似しており、タスクを実行し、結果を返します.
結果は図のようになります.
5050 Process finished with exit code 0
このような和を求めることもソートすることもFORKJOINの考え方で実現できるので、皆さんの役に立つことを願っています.
public class ForkJoin extends RecursiveTask {
public static final int threshold = 2;
private int start;
private int end;
public ForkJoin(int start, int end){
this.start = start;
this.end = end;
}
@Override
protected Integer compute() {
int sum = 0;
boolean bool = (end - start)/2 <= threshold;
if(bool){
for(int i = start; i<= end;i++){
sum += i;
}
} else {
int center = (start+end)/2;
ForkJoin one = new ForkJoin(start,center);
ForkJoin two = new ForkJoin(center+1,end);
one.fork();//
two.fork();
int oneResult = one.join();//
int twoResult = two.join();
sum = oneResult+twoResult;
}
return sum;
}
public static void main(String[] args) throws ExecutionException, InterruptedException {
ForkJoinPool pool = new ForkJoinPool();
ForkJoin forkJoin = new ForkJoin(1,100);
Future result = pool.submit(forkJoin);
int i = result.get();
System.out.print(i);
}
}
まず、RecursiveTaskクラスを継承していることがわかります.ForkJoinフレームワークを使用するには、まずForkJoinタスクを作成する必要があります.タスクでfork()とjoinを実行する操作メカニズムを提供します.通常、ForkjoinTaskクラスを直接継承するのではなく、サブクラスを直接継承する必要があります.
RecursiveAction:結果を返さない任 仕事
RecursiveTask:戻り値のあるタスクに使用します.ここで私が使っているのはRecursiveTaskで、ここのTは私たちが望んでいる結果のタイプです.また、computeメソッドを実装し、特定のタスクの詳細を定義する必要があります.
fork()はサブタスクを実行していることがわかります.
public final ForkJoinTask<V> fork() {
Thread t;
if ((t = Thread.currentThread()) instanceof ForkJoinWorkerThread)
((ForkJoinWorkerThread)t).workQueue.push(this);
else
ForkJoinPool.common.externalPush(this);
return this;
}
これはforkメソッドのソースコードです.
現在のタスクが実行中のプールでこのタスクを非同期で実行するか(適用される場合)、
ForkJoinPool.commonPool()
( そうでなければ
inForkJoinPool()
)非同期実行.これはjava apiの解釈で、明らかに私たちのタスクをワークキューに追加しました.forkメソッドは、私たちのタスクの結果を得て、結果を集約して私たちのタスクを定義します.累積です.
次にmainメソッドのコードを見てみましょう.ForkJoinPoolとは何ですか.ソースコードを見るとpublic class ForkJoinPool extends AbstractExecutorServiceが見つかります.そうです.ForkJoinPoolはforkjoinフレームワークのためにカスタマイズされたスレッドプールです.具体的な実装の詳細は見ないでください.submitを見るとよく知っているのではないでしょうか.そうです.私もそうです.この方法を見るとcallableインタフェースを思い出しました.実際には、私たちが推測したように、この2つの方法の役割は類似しており、タスクを実行し、結果を返します.
結果は図のようになります.
5050 Process finished with exit code 0
このような和を求めることもソートすることもFORKJOINの考え方で実現できるので、皆さんの役に立つことを願っています.