public abstract class ForkJoinTask<V> extends Object implements Future<V>, Serializable
ForkJoinPool内で実行する抽象基底クラスです。ForkJoinTaskは、通常のスレッドよりはるかに軽量な、スレッドに似たエンティティです。ある程度の使用制限を犠牲にして、ForkJoinPool内の少ない数の実際のスレッドで、膨大な数のタスクやサブタスクをホストできます。
メインのForkJoinTaskは、ForkJoinPoolに明示的に送信されたときに実行を開始します。ForkJoinの計算にまだ関与していない場合は、fork()、invoke()または関連メソッドを介してForkJoinPool.commonPool()で開始されます。起動されたあと、通常は次に、ほかのサブタスクを起動します。このクラスの名前で示されているように、ForkJoinTaskを使用している多くのプログラムはfork()メソッドとjoin()メソッド、またはinvokeAllなどの派生メソッドのみを使用します。ただし、このクラスはまた、高度な使用方法で効果を発揮するその他のいくつかのメソッドや、新しい形式の分岐/結合処理のサポートを可能にする拡張機能も提供します。
ForkJoinTaskは、軽量な形式のFutureです。ForkJoinTaskの効率は、純粋な関数を計算するか、または純粋に切り離されたオブジェクトに対して動作するという、計算タスクとしての主要な使用方法を反映する(部分的に静的にしか強制できない)一連の制限から得られます。主な調整メカニズムには、非同期実行を調整するfork()や、タスクの結果が計算されるまで処理を続行しないjoin()があります。計算は、理想的にはsynchronizedメソッドまたはブロックを回避するべきであり、また他のタスクの結合や、分岐/結合スケジューリングと連携するために通知されるPhaserなどのシンクロナイザの使用を除き、その他の同期のブロックを最小限に抑えるべきです。分割可能なタスクもまた、入出力のブロックを実行するべきではなく、また理想的には実行中の他のタスクからアクセスされる変数とは完全に独立している変数にアクセスするべきです。これらのガイドラインは、IOExceptionsなどのチェック例外をスローできないようにすることによって、緩やかに適用されます。ただし、計算では、結合しようとしている呼出し側に再スローされる非チェック例外が引き続き発生する可能性があります。これらの例外には、さらに、内部タスク・キューの割当て失敗などの内部リソースの不足によって生成されるRejectedExecutionExceptionが含まれる可能性があります。再スローされた例外は通常の例外と同じように動作しますが、可能な場合は、計算を開始したスレッドと実際に例外が発生しているスレッドの両方(最小限としては後者のみ)の(たとえば、ex.printStackTrace()を使用して表示された)スタック・トレースを含みます。
ブロックされるForkJoinTaskを定義して使用できますが、その場合はさらに3つの点を考慮する必要があります。(1)他のタスクが外部同期または入出力でブロックされるタスクに依存する必要がある場合は、少数の完了。結合されないイベント形式の非同期タスク(たとえば、CountedCompleterをサブクラス化するもの)は、多くの場合このカテゴリに入ります。(2)リソースへの影響を最小限に抑えるには、タスクを小さくして、理想的には(おそらく)ブロック・アクションしか実行しないようにする必要があります。(3) ForkJoinPool.ManagedBlocker APIを使用しない場合や、ブロックされる可能性があるタスクの数がプールのForkJoinPool.getParallelism()のレベルより小さいことがわかっている場合、そのプールでは、処理の進行や良好なパフォーマンスを確保するだけの十分なスレッドが使用できることを保証できません。
完了を待機し、タスクの結果を抽出するための主要メソッドはjoin()ですが、いくつかのバリアントが存在します。Future.get()メソッドは、完了に対する割込み可能な待機または時間指定された待機、あるいはその両方をサポートし、Futureの規則を使用して結果を報告します。invoke()メソッドは、意味的にはfork(); join()と同等ですが、常に現在のスレッドで実行を開始しようとします。これらのメソッドの「非出力」形式は、結果を抽出せず、例外も報告しません。これらは、一連のタスクが実行されていて、そのすべてが完了するまで結果または例外の処理を遅らせる必要がある場合に役立つことがあります。invokeAllメソッド(複数のバージョンで使用可能)は、もっとも一般的な形式の並列呼出し、つまり一連のタスクのフォークと、そのすべての結合を実行します。
もっとも一般的な用途では、分岐/結合ペアが並列的な再帰関数からの呼出し(分岐)と復帰(結合)のように動作します。他の形式の再帰呼出しと同様に、復帰(結合)はもっとも深いものを最初に実行する必要があります。たとえば、a.fork(); b.fork(); b.join(); a.join();は、bの前にaを結合するより、かなり効率的である可能性があります。
タスクの実行ステータスは、いくつかの詳細レベルで照会できます。isDone()は、タスクが何らかの方法で完了した場合(タスクが実行なしで取り消された場合を含む)にtrueになります。isCompletedNormally()は、タスクが取消しがなく、例外も発生せずに完了した場合にtrueになります。isCancelled()は、タスクが取り消された場合にtrueになります(この場合、getException()はCancellationExceptionを返します)。isCompletedAbnormally()は、タスクが取り消されか、または例外が検出された場合にtrueになります。この場合、getException()は、検出された例外またはCancellationExceptionのどちらかを返します。
ForkJoinTaskクラスは通常、直接にはサブクラス化されません。かわりに、特定のスタイルの分岐/結合処理をサポートする抽象クラスのいずれかをサブクラス化します。これは通常、結果を返さないほとんどの計算の場合はRecursiveAction、結果を返す計算の場合はRecursiveTask、完了したアクションが他のアクションをトリガーする計算の場合はCountedCompleterです。通常、具象ForkJoinTaskサブクラスは、コンストラクタで確立されたパラメータから成るフィールドを宣言してから、この基底クラスによって提供される制御メソッドを何らかの方法で使用するcomputeメソッドを定義します。
join()メソッドとそのバリアントが使用に適しているのは、完了の依存関係が非循環式である場合、つまり、並列計算を無閉路有向グラフ(DAG)として記述できる場合だけです。それ以外の場合は、タスクが循環的に互いを待機するため、実行によってある種のデッドロックが発生する可能性があります。ただし、このフレームワークでは、DAGとして静的に構造化されない問題のためのカスタム・サブクラスの構築に役立つ可能性のあるその他のメソッドや手法(たとえば、Phaser、helpQuiesce()、およびcomplete(V)の使用)がサポートされています。このような用途をサポートするため、setForkJoinTaskTag(short)またはcompareAndSetForkJoinTaskTag(short, short)を使用してForkJoinTaskをshort値で原子的にタグ付けし、getForkJoinTaskTag()を使用して確認できます。ForkJoinTaskの実装では、これらのprotectedメソッドまたはタグはどのような目的にも使用されませんが、特化されたサブクラスを構築するときに役立つ可能性があります。たとえば、並列的なグラフのトラバースでは、指定されたメソッドを使用して、すでに処理されているノードまたはタスクの再チェックを回避できます。(タグ付けのメソッド名は部分的に大きくなるため、それぞれの使用パターンを反映したメソッドを定義することをお薦めします。)
基本となる軽量タスク・スケジューリング・フレームワークに本質的に結び付けられた実装のオーバーライドを回避するために、ほとんどの基本サポート・メソッドはfinalです。新しい基本的なスタイルの分岐/結合処理を作成している開発者は、protectedメソッド、exec()、setRawResult(V)、およびgetRawResult()の実装を最小限にする一方で、そのサブクラスで(おそらく、このクラスによって提供されるほかのprotectedメソッドを使用して)実装できる抽象計算メソッドも導入するようにしてください。
ForkJoinTaskでは、比較的少ない量の計算を実行するようにしてください。大きなタスクは、通常は再帰的分解を使用して、より小さなサブタスクに分割するようにしてください。非常に大まかな経験則として、1つのタスクでは100より多く10000より少ない基本的な計算ステップを実行するようにし、無期限ループを回避するようにしてください。タスクが大きすぎると、並列性によってスループットを向上させることができません。小さすぎると、メモリーや内部タスク保守のオーバーヘッドによって処理効率が低下する可能性があります。
このクラスは、ForkJoinTasksの実行をほかの種類のタスクと混在させるときに役立つ可能性のある、RunnableおよびCallableのためのadaptメソッドを提供します。すべてのタスクがこの形式である場合は、asyncModeで構築されたプールの使用を検討してください。
ForkJoinTaskはSerializableです。これにより、リモート実行フレームワークなどの拡張機能で使用できるようになります。タスクの直列化は、実行中ではなく、実行の前またはあとにのみ行うのが適切です。実行中は直列化自体が使用されません。
| コンストラクタと説明 |
|---|
ForkJoinTask() |
| 修飾子と型 | メソッドと説明 |
|---|---|
static <T> ForkJoinTask<T> |
adapt(Callable<? extends T> callable)
指定された
Callableのcallメソッドをアクションとして実行する新しいForkJoinTaskを返し、その結果をjoin()実行時に返し、発生したチェック例外をRuntimeExceptionに変換します。 |
static ForkJoinTask<?> |
adapt(Runnable runnable)
|
static <T> ForkJoinTask<T> |
adapt(Runnable runnable, T result)
|
boolean |
cancel(boolean mayInterruptIfRunning)
このタスクの実行の取消しを試みます。
|
boolean |
compareAndSetForkJoinTaskTag(short e, short tag)
このタスクのタグ値を原子的に条件付きで設定します。
|
void |
complete(V value)
このタスクを実行し、中断または取り消しされていない場合、
joinの後続の呼び出しおよび関連の操作の結果として指定された値を返します。 |
void |
completeExceptionally(Throwable ex)
このタスクを強制的に実行し、中断または取り消しされていない場合は、
joinおよび関連の操作の実行時に指定された例外がスローされます。 |
protected abstract boolean |
exec()
このタスクのベース・アクションをただちに実行し、このメソッドからの復帰時にこのタスクが正常に完了したことが保証される場合はtrueを返します。
|
ForkJoinTask<V> |
fork()
現在のタスクが実行されているプール内でこのタスクを非同期で実行するように調整します(該当する場合)。
inForkJoinPool()でない場合は、ForkJoinPool.commonPool()を使用します。 |
V |
get()
必要に応じて計算が完了するまで待機し、その後、計算結果を取得します。
|
V |
get(long timeout, TimeUnit unit)
必要に応じて、最大で指定された時間、計算が完了するまで待機し、その後、計算結果が利用可能な場合は結果を取得します。
|
Throwable |
getException()
基本計算によってスローされた例外を返します。取り消された場合は
CancellationException、ない場合またはメソッドがまだ実行されていない場合はnullを返します。 |
short |
getForkJoinTaskTag()
このタスクのタグを返します。
|
static ForkJoinPool |
getPool()
現在のタスク実行をホストするプール、またはこのタスクがForkJoinPoolの外部で実行している場合はnullを返します。
|
static int |
getQueuedTaskCount()
現在のワーカー・スレッドによってフォークされたが、まだ実行されていないタスクの推定数を返します。
|
abstract V |
getRawResult()
このタスクが異常な状態で実行された場合であっても、
join()によって返される結果を返します。このタスクが実行されたかどうかが不明の場合は、nullです。 |
static int |
getSurplusQueuedTaskCount()
現在のワーカー・スレッドによって保持されているローカルのキューに入っているタスクが、それを横取りする可能性がある他のワーカー・スレッドよりもどれだけ多いかの推定値を返します。このスレッドがForkJoinPoolで動作していない場合はゼロを返します。
|
static void |
helpQuiesce()
現在のタスクをホストしているプールが
休止中になるまでタスクを実行する可能性があります。 |
static boolean |
inForkJoinPool()
現在のスレッドが、ForkJoinPool計算として実行される
ForkJoinWorkerThreadの場合、trueを返します。 |
V |
invoke()
このタスクの実行を開始し、必要な場合は完了まで待機し、その結果を返すか、基本となる計算がそうである場合は、(チェックされない)
RuntimeExceptionまたはErrorをスローします。 |
static <T extends ForkJoinTask<?>> |
invokeAll(Collection<T> tasks)
指定されたコレクション内のすべてのタスクをフォークし、各タスクに対して
isDoneが適用されるか、(チェックされない)例外が発生する場合に復帰します。後者の場合、例外が再スローされます。 |
static void |
invokeAll(ForkJoinTask<?>... tasks)
指定されたタスクをフォークし、各タスクに対して
isDoneが適用されるか、(チェックされない)例外が発生する場合に復帰します。後者の場合、例外が再スローされます。 |
static void |
invokeAll(ForkJoinTask<?> t1, ForkJoinTask<?> t2)
指定されたタスクをフォークし、各タスクに対して
isDoneが適用されるか、(チェックされない)例外が発生する場合に復帰します。後者の場合、例外が再スローされます。 |
boolean |
isCancelled()
このタスクが正常に完了する前に取り消された場合は
trueを返します。 |
boolean |
isCompletedAbnormally()
このタスクが例外をスローしたか取り消された場合は
trueを返します。 |
boolean |
isCompletedNormally()
このタスクが例外をスローせずに完了し、取り消されなかった場合は
trueが返されます。 |
boolean |
isDone()
このタスクが完了した場合は
trueを返します。 |
V |
join()
計算が完了した
あと、計算の結果を返します。 |
protected static ForkJoinTask<?> |
peekNextLocalTask()
現在のスレッドによってキューに入れられたがまだ実行されていないタスクがすぐに使用できる場合、そのタスクを返し、スケジュール解除や実行は行いません。
|
protected static ForkJoinTask<?> |
pollNextLocalTask()
現在のスレッドがForkJoinPoolで動作している場合に、現在のスレッドによってキューに入れられたがまだ実行されていない次のタスクを、実行せずにスケジュール解除して復帰します。
|
protected static ForkJoinTask<?> |
pollTask()
現在のスレッドがForkJoinPoolで動作しており、現在のスレッドによってキューに入れられたがまだ実行されていない次のタスクが使用可能な場合、そのタスクを実行せずにスケジュール解除して復帰します。そのようなタスクが使用可能でない場合は、他のスレッドによってフォークされたタスクが対象になります(使用可能な場合)。
|
void |
quietlyComplete()
値を設定せずにこのタスクを正常に完了します。
|
void |
quietlyInvoke()
このタスクの実行を開始し、必要な場合は完了まで待機しますが、その結果を返したり例外をスローしたりしません。
|
void |
quietlyJoin()
このタスクを結合し、その結果を返したり例外をスローしたりしません。
|
void |
reinitialize()
このタスクの内部登録状態をリセットし、後続の
forkを許可します。 |
short |
setForkJoinTaskTag(short tag)
このタスクのタグ値を原子的に設定します。
|
protected abstract void |
setRawResult(V value)
指定された値を結果として返すことを強制します。
|
boolean |
tryUnfork()
このタスクの実行のスケジュール解除を試みます。
|
public final ForkJoinTask<V> fork()
inForkJoinPool()でない場合は、ForkJoinPool.commonPool()を使用します。必ずしも適用されるわけではありませんが、タスクが完了して再初期化されないかぎり、タスクを複数回フォークすることは使用方法のエラーです。このタスクの状態やその操作対象の任意のデータへの以降の変更は、その前にjoin()または関連するメソッドを呼び出すか、またはtrueを返すisDone()を呼び出さないかぎり、そのタスクを実行しているスレッド以外のスレッドが必ずしも一貫して監視できるわけではありません。this、使用方法を単純化するためpublic final V join()
あと、計算の結果を返します。このメソッドは、異常な完了によってExecutionExceptionではなく、RuntimeExceptionまたはErrorが発生する点、および呼出し側スレッドの割り込みのためにメソッドがInterruptedExceptionをスローして突然復帰することがないという点で、get()とは異なります。public final V invoke()
RuntimeExceptionまたはErrorをスローします。public static void invokeAll(ForkJoinTask<?> t1, ForkJoinTask<?> t2)
isDoneが適用されるか、(チェックされない)例外が発生する場合に復帰します。後者の場合、例外が再スローされます。複数のタスクで例外が発生する場合、このメソッドはこれらのいずれかの例外をスローします。いずれかのタスクで例外が発生した場合は、ほかのタスクが取り消されることがあります。ただし、個々のタスクの実行ステータスは例外が返された時点で保証されません。各タスクのステータスは、タスクが取り消されたか、正常に完了したか、例外が発生したか、未処理のままかを確認するための、getException()および関連メソッドによって取得できます。t1 - 最初のタスクt2 - 2番目のタスクNullPointerException - いずれかのタスクがnullの場合public static void invokeAll(ForkJoinTask<?>... tasks)
isDoneが適用されるか、(チェックされない)例外が発生する場合に復帰します。後者の場合、例外が再スローされます。複数のタスクで例外が発生する場合、このメソッドはこれらのいずれかの例外をスローします。いずれかのタスクで例外が発生した場合、ほかのタスクが取り消される場合があります。ただし、個々のタスクの実行ステータスは例外が返された時点で保証されません。各タスクのステータスは、タスクが取り消されたか、正常に完了したか、例外が発生したか、未処理のままかを確認するための、getException()および関連メソッドによって取得できます。tasks - タスクNullPointerException - いずれかのタスクがnullの場合public static <T extends ForkJoinTask<?>> Collection<T> invokeAll(Collection<T> tasks)
isDoneが適用されるか、(チェックされない)例外が発生する場合に復帰します。後者の場合、例外が再スローされます。複数のタスクで例外が発生する場合、このメソッドはこれらのいずれかの例外をスローします。いずれかのタスクで例外が発生した場合、ほかのタスクが取り消される場合があります。ただし、個々のタスクの実行ステータスは例外が返された時点で保証されません。各タスクのステータスは、タスクが取り消されたか、正常に完了したか、例外が発生したか、未処理のままかを確認するための、getException()および関連メソッドによって取得できます。T - タスクから返される値の型tasks - タスクのコレクションNullPointerException - タスクまたはいずれかの要素がnullの場合public boolean cancel(boolean mayInterruptIfRunning)
cancelが呼び出されたときにこのタスクが起動されていない場合、このタスクの実行は抑制されます。このメソッドが正常に復帰したあとは、reinitialize()への介入する呼出しが存在しないかぎり、isCancelled()、isDone()、およびcancelの以降の呼出しではtrueが返され、join()および関連するメソッドの呼出しではCancellationExceptionが発生します。
このメソッドはサブクラスでオーバーライドできますが、その場合でも、引き続きこれらのプロパティが保持されるようにする必要があります。特に、cancelメソッド自体が例外をスローしてはいけません。
このメソッドは、ほかのタスクから呼び出されるように設計されています。現在のタスクを終了するには、その計算メソッドから非チェック例外を返すか、またはスローするか、あるいはcompleteExceptionally(Throwable)を呼び出すのみで済みます。
public final boolean isDone()
Futuretrueを返します。完了の理由は、正常終了、例外、取り消しなどがありますが、いずれの場合もこのメソッドはtrueを返します。public final boolean isCancelled()
Futuretrueを返します。isCancelled、インタフェース: Future<V>truepublic final boolean isCompletedAbnormally()
trueを返します。truepublic final boolean isCompletedNormally()
trueが返されます。truepublic final Throwable getException()
CancellationException、ない場合またはメソッドがまだ実行されていない場合はnullを返します。nullpublic void completeExceptionally(Throwable ex)
joinおよび関連の操作の実行時に指定された例外がスローされます。このメソッドを使用すると、非同期タスクで例外を引き起こしたり、それ以外の方法では完了しないタスクの完了を強制したりすることができます。これをほかの状況で使用することは推奨されていません。このメソッドはオーバーライド可能ですが、オーバーライドされたバージョンは保証を維持するためにsuper実装を起動する必要があります。ex - スローする例外。この例外がRuntimeExceptionまたはErrorでない場合、スローされる実際の例外は、原因exを含むRuntimeExceptionになります。public void complete(V value)
joinの後続の呼び出しおよび関連の操作の結果として指定された値を返します。このメソッドを使用すると、非同期タスクに結果を提供したり、それ以外の方法では正常に完了しないタスクに代わりの処理方法を提供したりすることができます。これをほかの状況で使用することは推奨されていません。このメソッドはオーバーライド可能ですが、オーバーライドされたバージョンは保証を維持するためにsuper実装を起動する必要があります。value - このタスクの結果値public final void quietlyComplete()
public final V get() throws InterruptedException, ExecutionException
get、インタフェース: Future<V>CancellationException - 計算が取り消された場合ExecutionException - 計算で例外がスローされた場合InterruptedException - 現在のスレッドがForkJoinPoolのメンバーでなく、待機中に割込みが発生した場合public final V get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException
get、インタフェース: Future<V>timeout - 待機する最長時間unit - timeout引数の時間単位CancellationException - 計算が取り消された場合ExecutionException - 計算で例外がスローされた場合InterruptedException - 現在のスレッドがForkJoinPoolのメンバーでなく、待機中に割込みが発生した場合TimeoutException - 待機がタイム・アウトになった場合public final void quietlyJoin()
public final void quietlyInvoke()
public static void helpQuiesce()
休止中になるまでタスクを実行する可能性があります。このメソッドは、多数のタスクがフォークされるが、どのタスクも明示的には結合されず、代わりにすべてが処理されるまで実行する設計で役立つことがあります。public void reinitialize()
forkを許可します。このメソッドを使用すると、このタスクを繰返し再利用できますが、それが可能なのは、このタスクがフォークされていないか、またはフォークされたあとに完了し、かつこのタスクの未処理の結合もすべて完了しているときに再利用が発生した場合だけです。その他のすべての使用条件の下での効果は保証されません。このメソッドは、ループ内でサブタスクの事前に構築されたツリーを実行するときに役立つことがあります。
このメソッドが完了すると、isDone()はfalseを報告し、getException()はnullを報告します。ただし、getRawResultによって返される値は影響を受けません。この値をクリアするには、setRawResult(null)を呼び出すことができます。
public static ForkJoinPool getPool()
nullinForkJoinPool()public static boolean inForkJoinPool()
ForkJoinWorkerThreadの場合、trueを返します。ForkJoinWorkerThreadである場合はtrue。それ以外の場合はfalsepublic boolean tryUnfork()
truepublic static int getQueuedTaskCount()
public static int getSurplusQueuedTaskCount()
public abstract V getRawResult()
join()によって返される結果を返します。このタスクが実行されたかどうかが不明の場合は、nullです。このメソッドは、デバッグを支援したり、拡張機能をサポートするためのものです。これをほかのコンテキストで使用することは推奨されていません。null (完了しない場合)protected abstract void setRawResult(V value)
value - 値protected abstract boolean exec()
trueprotected static ForkJoinTask<?> peekNextLocalTask()
nullprotected static ForkJoinTask<?> pollNextLocalTask()
nullprotected static ForkJoinTask<?> pollTask()
nullの結果は、必ずしもこのタスクが動作しているプールの休止を示すわけではありません。このメソッドは主に拡張機能をサポートするためのもので、ほかの用途で使用されることはまれです。nullpublic final short getForkJoinTaskTag()
public final short setForkJoinTaskTag(short tag)
tag - タグ値public final boolean compareAndSetForkJoinTaskTag(short e,
short tag)
if (task.compareAndSetForkJoinTaskTag((short)0, (short)1))を確認し、falseの場合はノードがすでにチェックされているので終了するメソッドなどです。e - 予想されるタグ値tag - 新しいタグ値true。public static ForkJoinTask<?> adapt(Runnable runnable)
runnable - 実行可能アクションpublic static <T> ForkJoinTask<T> adapt(Runnable runnable, T result)
T - 結果の型runnable - 実行可能アクションresult - 完了時の結果public static <T> ForkJoinTask<T> adapt(Callable<? extends T> callable)
Callableのcallメソッドをアクションとして実行する新しいForkJoinTaskを返し、その結果をjoin()実行時に返し、発生したチェック例外をRuntimeExceptionに変換します。T - 呼出し可能タスクの結果の型callable - 呼出し可能なアクション バグまたは機能を送信
詳細なAPIリファレンスおよび開発者ドキュメントについては、Java SEのドキュメントを参照してください。そのドキュメントには、概念的な概要、用語の定義、回避方法、有効なコード例などの、開発者を対象にしたより詳細な説明が含まれています。
Copyright© 1993, 2014, Oracle and/or its affiliates. All rights reserved.