Fork/Join Frameworkは、複数のプロセスを実装できるExecutorserviceインターフェイスの実装です。 Fork/Joinは、すべてのリソースを最大限に活用してアプリケーションのパフォーマンスを可能な限り強化することを目的として、大きなタスクを複数の小さなタスクに再帰的に分割するために使用できます。
executorserviceインターフェイスの実装と同様に、Fork/Joinはスレッドプールを使用して、ワーカースレッドを分配的に管理します。 Fork/Join Frameworkのユニークな点は、ワークスチールアルゴリズムを使用することです。このアルゴリズムを介して、ワーカースレッドは、他の忙しいスレッドタスクを盗んで、何もできないときに実行することができます。
Fork/Join Frameworkのコアは、AbstractExecutorserviceクラスのサブクラスであるForkjoinpoolクラスです。 Forkjoinpoolは、コアワークスティールアルゴリズムを実装し、ForkJointask処理を実行できます。
基本的な使用法
Fork/Join Frameworkを使用する最初のステップは、断片化されたタスクを実行するコードを作成することです。記述するコードは、次の擬似コードに似ています。
タスクが十分に小さい場合:タスクを直接実行します。他のタスク:2つの小さなタスクにタスクをカットして2つの小さなタスクを実行し、結果を待ちます
上記のようにコードをカプセル化するには、ForkJointaskサブクラスを使用してください。通常、recursivetask(このクラスが結果を返します)と再婚diveを含むJDKが提供するいくつかのクラスが使用されます。
Forkjointaskサブクラスを準備した後、すべてのタスクを表すオブジェクトを作成し、ForkjoinpoolインスタンスのInvoke()メソッドに渡します。
ぼかしからクリアまで
Fork/Join Frameworkの仕組みを理解するために、ケースを使用して説明します。たとえば、画像をぼかします。整数アレイを使用して画像を表します。各数値はピクセルの色を表します。ぼやけた画像は、同じ長さの配列でも表されます。
ぼかしの実行は、画像を表す各ピクセルを処理することで実現されます。各ピクセルとその周囲のピクセルの平均(赤、黄、青の3つの主要な色の平均)を計算し、結果の結果の配列はぼやけた画像です。通常、画像の表現は大きな配列であるため、プロセス全体には通常、多くの時間がかかります。 Fork/Join Frameworkを使用して、マルチプロセッサシステムの同時処理の利点を活用して高速化できます。可能な実装は次のとおりです。
パッケージcom.zhyea.robin; java.util.concurrent.recursiveactionをインポートします。 Public Class ForkblurはrecursiveActionを拡張します{private int [] msource; Private int mstart; private int mlength;プライベートint [] mdestination; //ウィンドウサイズを処理します。奇数である必要があります。 private int mblurwidth = 15; public forkblur(int [] src、int start、int length、int [] dst){msource = src; mstart = start; mlength = length; mdestination = dst; } protected void computedirectly(){int sidepixels =(mblurwidth -1) / 2; for(int index = mstart; index <mstart+mlength; index ++){//平均値を計算します。 float rt = 0、gt = 0、bt = 0; for(int mi = -sidepixels; mi <= sidepixels; mi ++){int mindex = math.min(math.max(mi+index、0)、msource.length -1); int pixel = msource [mindex]; rt +=(float)((pixel&0x00ff0000)>> 16) / mblurwidth; gt +=(float)((pixel&0x00000ff00)>> 8) / mblurwidth; bt +=(float)((pixel&0x000000ff)>> 0) / mblurwidth; } //ターゲットピクセルを再編成します。 int dpixel =(0xff0000000)| (((int)rt)<< 16)| (((int)gt)<< 8)| (((int)bt)<< 0); mdestination [index] = dpixel; }} ....}次に、両方のファジー操作が実装され、タスクを2つの小さなタスクに分割する抽象メソッドcompute()を実装します。ここでは、タスクを直接実行するか、配列の長さに基づいて2つの小さなタスクに分割するかを決定するだけです。
保護された静的int sthreshold = 100000; protected void compute(){if(mlength <sthreshold){computedirectly();戻る; } int split = mlength / 2; Invokeall(新しいForkblur(Msource、Mstart、Split、Mdestination)、New Forkblur(Msource、Mstart + Split、Mlength -Split、Mdestination)); }上記のメソッドの実装は再帰反応のサブクラスで定義されるため、タスクを作成してForkjoinpoolで直接実行できます。特定の手順は次のとおりです。
1.実行するタスクを表すオブジェクトを作成します。
// SRCは、ソースイメージのピクセルの配列を表します// DSTは、生成された画像のピクセルを表しますforkblur fb = new forkblur(src、0、src.length、dst);
2。タスクを実行するForkjoinpoolインスタンスを作成します。
ForkJoinPool pool = new ForkJoinPool();
3。タスクを実行します:
pool.invoke(fb);
ソースコードには、ターゲット画像を作成するコードも含まれています。詳細については、Forkblurの例を参照してください。
標準実装
Fork/Join Frameworkを使用して、カスタムアルゴリズムに従ってマルチコアシステムで同時タスクを実行するには、もちろん、カスタムクラス(以前に実装したForkblurクラスなど)を実装する必要があります。さらに、Fork/Joinフレームワークのいくつかの機能がJavaseで広く使用されています。たとえば、java8のjava.util.arraysクラスのParallelsort()メソッドは、フォーク/Joinフレームワークを使用します。詳細については、Java APIドキュメントを参照してください。
Fork/Join Frameworkの別の実装は、Java.tile.streamsパッケージの下にあります。これは、Java8のLambda機能の一部でもあります。