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()
Future
true
を返します。完了の理由は、正常終了、例外、取り消しなどがありますが、いずれの場合もこのメソッドはtrue
を返します。public final boolean isCancelled()
Future
true
を返します。isCancelled
、インタフェース: Future<V>
true
public final boolean isCompletedAbnormally()
true
を返します。true
public final boolean isCompletedNormally()
true
が返されます。true
public final Throwable getException()
CancellationException
、ない場合またはメソッドがまだ実行されていない場合はnull
を返します。null
public 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()
null
inForkJoinPool()
public static boolean inForkJoinPool()
ForkJoinWorkerThread
の場合、true
を返します。ForkJoinWorkerThread
である場合はtrue
。それ以外の場合はfalse
public boolean tryUnfork()
true
public 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()
true
protected static ForkJoinTask<?> peekNextLocalTask()
null
protected static ForkJoinTask<?> pollNextLocalTask()
null
protected static ForkJoinTask<?> pollTask()
null
の結果は、必ずしもこのタスクが動作しているプールの休止を示すわけではありません。このメソッドは主に拡張機能をサポートするためのもので、ほかの用途で使用されることはまれです。null
public 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.