ThreadPoolExecutor クラス
定義
重要
一部の情報は、リリース前に大きく変更される可能性があるプレリリースされた製品に関するものです。 Microsoft は、ここに記載されている情報について、明示または黙示を問わず、一切保証しません。
通常は ExecutorService
ファクトリ メソッドを使用して構成される、複数のプールされたスレッドのいずれかを使用して、送信された各タスクを Executors
実行する 。
[Android.Runtime.Register("java/util/concurrent/ThreadPoolExecutor", DoNotGenerateAcw=true)]
public class ThreadPoolExecutor : Java.Util.Concurrent.AbstractExecutorService
[<Android.Runtime.Register("java/util/concurrent/ThreadPoolExecutor", DoNotGenerateAcw=true)>]
type ThreadPoolExecutor = class
inherit AbstractExecutorService
- 継承
- 派生
- 属性
注釈
通常は ExecutorService
ファクトリ メソッドを使用して構成される、複数のプールされたスレッドのいずれかを使用して、送信された各タスクを Executors
実行する 。
スレッド プールは、2 つの異なる問題に対処します。通常、タスクごとの呼び出しオーバーヘッドが減るため、多数の非同期タスクを実行するとパフォーマンスが向上し、タスクのコレクションの実行時に使用されるスレッドを含むリソースを境界化および管理する手段が提供されます。 また、完了 ThreadPoolExecutor
したタスクの数など、基本的な統計情報も保持されます。
幅広いコンテキストで役立つこのクラスには、多くの調整可能なパラメーターと拡張性フックが用意されています。 ただし、プログラマは、最も一般的な使用シナリオの設定を事前に構成する、より便利な Executors
ファクトリ メソッド Executors#newCachedThreadPool
(無制限のスレッド プール、自動スレッド再利用あり) Executors#newFixedThreadPool
、(固定サイズのスレッド プール)、および Executors#newSingleThreadExecutor
(単一のバックグラウンド スレッド) を使用することをお勧めします。 それ以外の場合は、このクラスを手動で構成してチューニングする場合は、次のガイドを使用します。
<dl>
<dt>Core と最大プール サイズ</dt>
<dd>A ThreadPoolExecutor
は、corePoolSize (を参照) と maximumPoolSize (を参照#getPoolSize
#getCorePoolSize
) によって設定された境界に従ってプール サイズを自動的に調整します (「」を参照)。#getMaximumPoolSize
メソッド #execute(Runnable)
で新しいタスクが送信されると、corePoolSize スレッドが実行されている数より少ない場合は、他のワーカー スレッドがアイドル状態であっても、要求を処理する新しいスレッドが作成されます。 それ以外の場合は、maximumPoolSize スレッドが実行されているよりも少ない場合は、キューがいっぱいの場合にのみ要求を処理する新しいスレッドが作成されます。 corePoolSize と maximumPoolSize を同じに設定することで、固定サイズのスレッド プールを作成します。 maximumPoolSize を などの本質的に無制限の値 Integer.MAX_VALUE
に設定すると、プールは任意の数の同時実行タスクに対応できます。 通常、コア および 最大プール サイズは構築時にのみ設定されますが、 と #setMaximumPoolSize
を使用して#setCorePoolSize
動的に変更することもできます。 </Dd>
<dt>オンデマンド構築</dt>
<dd>既定では、コア スレッドも最初に作成され、新しいタスクが到着したときにのみ開始されますが、これは メソッド #prestartCoreThread
または #prestartAllCoreThreads
を使用して動的にオーバーライドできます。 空でないキューを使用してプールを構築する場合は、スレッドを事前に開始する必要があります。 </Dd>
<dt>新しいスレッド<の作成/dt>
<dd>新しいスレッドは を ThreadFactory
使用して作成されます。 それ以外の場合は、 Executors#defaultThreadFactory
が使用され、すべてのスレッドが同じであり、同じThreadGroup
NORM_PRIORITY
優先度とデーモン以外の状態になります。 別の ThreadFactory を指定することで、スレッドの名前、スレッド グループ、優先度、デーモンの状態などを変更できます。 ThreadFactory
から newThread
null を返して要求されたときに がスレッドの作成に失敗した場合、Executor は続行されますが、タスクを実行できない可能性があります。 スレッドには、"modifyThread" RuntimePermission
が含まれている必要があります。 ワーカー スレッドまたはプールを使用する他のスレッドがこのアクセス許可を持っていない場合、サービスが低下する可能性があります。構成の変更はタイムリーに有効にされず、シャットダウン プールは終了は可能だが完了していない状態のままになる可能性があります。</Dd>
<dt>Keep-alive times</dt>
<dd>プールに現在 corePoolSize スレッドを超えている場合、余分なスレッドが keepAliveTime を超えてアイドル状態になっている場合は終了します (を参照)。#getKeepAliveTime(TimeUnit)
これにより、プールがアクティブに使用されていない場合のリソース消費量を減らすことができます。 後でプールがよりアクティブになると、新しいスレッドが構築されます。 このパラメーターは、 メソッド #setKeepAliveTime(long, TimeUnit)
を使用して動的に変更することもできます。 の値を使用すると、アイドル状態の Long.MAX_VALUE
TimeUnit#NANOSECONDS
スレッドがシャットダウン前に終了することが事実上無効になります。 既定では、キープアライブ ポリシーは corePoolSize スレッドを超える場合にのみ適用されますが、keepAliveTime 値が 0 でない限り、メソッド #allowCoreThreadTimeOut(boolean)
を使用してコア スレッドにもこのタイムアウト ポリシーを適用できます。 </Dd>
<dt>Queuing</dt>
<dd>Any BlockingQueue
は、送信されたタスクを転送および保持するために使用できます。 このキューの使用は、プールのサイズ設定と対話します。
<ul>
<li>実行中の corePoolSize スレッドより少ない場合、Executor は常にキューではなく新しいスレッドを追加することを好みます。
<li>corePoolSize 以上のスレッドが実行されている場合、Executor は常に新しいスレッドを追加するのではなく、要求をキューに入れることを好みます。
<li>要求をキューに入れることができない場合、maximumPoolSize を超えない限り、新しいスレッドが作成されます。この場合、タスクは拒否されます。
</ul>
キューには、次の 3 つの一般的な方法があります。 <>
<li><em> Direct ハンドオフ。</em> 作業キューの適切な既定の選択肢は、タスクを SynchronousQueue
保持せずにスレッドに提供することです。 ここで、タスクをすぐに実行できるスレッドがない場合、タスクをキューに登録しようとすると失敗するため、新しいスレッドが構築されます。 このポリシーは、内部依存関係を持つ可能性がある一連の要求を処理するときにロックアップを回避します。 直接ハンドオフでは、通常、送信された新しいタスクが拒否されないように、無制限の maximumPoolSizes が必要です。 これにより、コマンドが処理できるよりも平均して速く到着し続けると、無制限のスレッドが増加する可能性が認められます。
<li><em> 無制限のキュー。</em> 無制限のキュー (たとえば LinkedBlockingQueue
、事前に定義された容量のない ) を使用すると、すべての corePoolSize スレッドがビジー状態になると、キューで新しいタスクが待機します。 したがって、corePoolSize スレッド以外のスレッドは作成されません。 (そのため、maximumPoolSize の値には影響はありません)。これは、各タスクが他のタスクから完全に独立している場合に適切な場合があるため、タスクは互いの実行に影響を与えることはできません。たとえば、Web ページ サーバーの場合などです。 このスタイルのキューは、要求の一時的なバーストをスムーズ化するのに役立ちますが、コマンドが処理よりも平均して速く到着し続けると、無制限の作業キューの増加の可能性が認められます。
<li><em>Bounded queues.</em> 境界付きキュー (たとえば、 ) は、 ArrayBlockingQueue
有限の maximumPoolSizes で使用する場合にリソースの枯渇を防ぐのに役立ちますが、調整と制御が困難になる可能性があります。 キュー サイズと最大プール サイズは相互にトレードオフされる可能性があります。大きなキューと小さなプールを使用すると、CPU 使用率、OS リソース、コンテキスト切り替えオーバーヘッドが最小限に抑えられますが、人為的にスループットが低下する可能性があります。 タスクが頻繁にブロックされる場合 (たとえば、I/O バインドされている場合)、システムは、他の方法で許可するよりも多くのスレッドの時間をスケジュールできる可能性があります。 小さなキューを使用するには、一般にプール サイズが大きく必要です。これにより CPU の使用が増えますが、許容できないスケジューリング オーバーヘッドが発生する可能性があり、スループットも低下します。
</Ol>
</Dd>
<dt>Rejected tasks</dt>
<dd>メソッド#execute(Runnable)
で送信された<新しいタスクは><、Executor がシャットダウンされたとき、および Executor が最大スレッドと作業キュー容量の両方に有限の境界を使用し、飽和状態になると、拒否/em> になります。 どちらの場合も、 メソッドは execute
の メソッドRejectedExecutionHandler
をRejectedExecutionHandler#rejectedExecution(Runnable, ThreadPoolExecutor)
呼び出します。 次の 4 つの定義済みハンドラー ポリシーが提供されます。
<Ol>
<li>既定 ThreadPoolExecutor.AbortPolicy
では、ハンドラーは拒否時にランタイム RejectedExecutionException
をスローします。
<li>では ThreadPoolExecutor.CallerRunsPolicy
、それ自体を呼び出す execute
スレッドによってタスクが実行されます。 これにより、新しいタスクが送信される速度が遅くなる簡単なフィードバック制御メカニズムが提供されます。
<li>では ThreadPoolExecutor.DiscardPolicy
、実行できないタスクは単に削除されます。 このポリシーは、タスクの完了に依存しないまれなケースに対してのみ設計されています。
<li>では ThreadPoolExecutor.DiscardOldestPolicy
、Executor がシャットダウンされていない場合、作業キューの先頭にあるタスクが削除され、実行が再試行されます (再度失敗する可能性があり、これが繰り返されます)。このポリシーを受け入れることはほとんどありません。 ほとんどの場合、ドキュメントに示すように、タスクを取り消して、完了を待機しているコンポーネントで例外を発生させたり、エラーをログに ThreadPoolExecutor.DiscardOldestPolicy
記録したりする必要もあります。
</Ol>
他の種類の RejectedExecutionHandler
クラスを定義して使用することもできます。 これを行うには、特にポリシーが特定の容量またはキュー ポリシーでのみ機能するように設計されている場合は、何らかの注意が必要です。 </Dd>
<dt>Hook メソッド</dt>
<dd>このクラスは、各タスクの実行前と#afterExecute(Runnable, Throwable)
実行後に呼び出されるオーバーライド可能#beforeExecute(Thread, Runnable)
な メソッドと メソッドを提供protected
します。 これらは、実行環境を操作するために使用できます。たとえば、ThreadLocals の再初期化、統計の収集、ログ エントリの追加などです。 さらに、 メソッド #terminated
をオーバーライドして、Executor が完全に終了した後に実行する必要がある特別な処理を実行できます。
hook、callback、または BlockingQueue メソッドが例外をスローすると、内部ワーカー スレッドが失敗し、突然終了し、置き換えられる可能性があります。</Dd>
<dt>Queue maintenance</dt>
<dd>メソッド #getQueue()
を使用すると、監視とデバッグのために作業キューにアクセスできます。 他の目的でこのメソッドを使用することは強くお勧めしません。 2 つのメソッドが提供され#purge
、#remove(Runnable)
多数のキューに登録されたタスクが取り消されたときに記憶域の再利用を支援するために使用できます。</Dd>
<dt>Reclamation</dt>
<dd>プログラム <em>AND</em> で参照されなくなったプールに、スレッドが残っていない場合は、明示的にシャットダウンせずに再利用 (ガベージ コレクション) できます。 未使用のすべてのスレッドが最終的に終了するようにプールを構成するには、適切なキープアライブ時間を設定するか、コア スレッドの下限を使用するか、 を設定 #allowCoreThreadTimeOut(boolean)
します。 </Dd>
</Dl>
<b>拡張の例。</b> このクラスのほとんどの拡張機能は、保護されたフック メソッドの 1 つ以上をオーバーライドします。 たとえば、単純な一時停止/再開機能を追加するサブクラスを次に示します。
{@code
class PausableThreadPoolExecutor extends ThreadPoolExecutor {
private boolean isPaused;
private ReentrantLock pauseLock = new ReentrantLock();
private Condition unpaused = pauseLock.newCondition();
public PausableThreadPoolExecutor(...) { super(...); }
protected void beforeExecute(Thread t, Runnable r) {
super.beforeExecute(t, r);
pauseLock.lock();
try {
while (isPaused) unpaused.await();
} catch (InterruptedException ie) {
t.interrupt();
} finally {
pauseLock.unlock();
}
}
public void pause() {
pauseLock.lock();
try {
isPaused = true;
} finally {
pauseLock.unlock();
}
}
public void resume() {
pauseLock.lock();
try {
isPaused = false;
unpaused.signalAll();
} finally {
pauseLock.unlock();
}
}
}}
1\.5 で追加されました。
の java.util.concurrent.ThreadPoolExecutor
Java ドキュメント。
このページの一部は、によって作成および共有された作業に基づく変更であり、に記載されている条件に従って使用されます。
コンストラクター
ThreadPoolExecutor(Int32, Int32, Int64, TimeUnit, IBlockingQueue) |
指定された初期パラメーター Executors#defaultThreadFactory の既定のスレッド ファクトリと ThreadPoolExecutor を使用して、新しい |
ThreadPoolExecutor(Int32, Int32, Int64, TimeUnit, IBlockingQueue, IRejectedExecutionHandler) |
指定された初期パラメーターと Executors#defaultThreadFactory 既定のスレッド ファクトリを使用して、新しい |
ThreadPoolExecutor(Int32, Int32, Int64, TimeUnit, IBlockingQueue, IThreadFactory) |
指定された初期パラメーターと ThreadPoolExecutor を使用して、新しい |
ThreadPoolExecutor(Int32, Int32, Int64, TimeUnit, IBlockingQueue, IThreadFactory, IRejectedExecutionHandler) |
指定された初期パラメーターを使用して新しい |
ThreadPoolExecutor(IntPtr, JniHandleOwnership) |
JNI オブジェクトのマネージド表現を作成するときに使用されるコンストラクター。ランタイムによって呼び出されます。 |
プロパティ
ActiveCount |
タスクをアクティブに実行しているスレッドのおおよその数を返します。 |
Class |
この |
CompletedTaskCount |
実行が完了したタスクのおおよその合計数を返します。 |
CorePoolSize |
スレッドのコア数を返します。 または、スレッドのコア数を設定します。 |
Handle |
基になる Android インスタンスへのハンドル。 (継承元 Object) |
IsShutdown |
通常は |
IsTerminated |
通常は |
IsTerminating |
この Executor が または |
JniIdentityHashCode |
通常は |
JniPeerMembers |
通常は |
LargestPoolSize |
プール内に同時に存在するスレッドの最大数を返します。 |
MaximumPoolSize |
許容されるスレッドの最大数を返します。 または、許容されるスレッドの最大数を設定します。 |
PeerReference |
通常は |
PoolSize |
プール内のスレッドの現在の数を返します。 |
Queue |
この Executor によって使用されるタスク キューを返します。 |
RejectedExecutionHandler |
実行できないタスクの現在のハンドラーを返します。 または、実行できないタスクの新しいハンドラーを設定します。 |
TaskCount |
実行がスケジュールされたタスクのおおよその合計数を返します。 |
ThreadFactory |
新しいスレッドの作成に使用されるスレッド ファクトリを返します。 または、新しいスレッドの作成に使用されるスレッド ファクトリを設定します。 |
ThresholdClass |
この API は Mono for Android インフラストラクチャをサポートしており、コードから直接使用するためのものではありません。 |
ThresholdType |
この API は Mono for Android インフラストラクチャをサポートしており、コードから直接使用するためのものではありません。 |
メソッド
AfterExecute(IRunnable, Throwable) |
指定された Runnable の実行が完了したときに呼び出されるメソッド。 |
AllowCoreThreadTimeOut(Boolean) |
キープアライブ時間内にタスクが到着しなかった場合にコア スレッドがタイムアウトして終了するかどうかを制御するポリシーを設定します。新しいタスクが到着したときに必要に応じて置き換えられます。 |
AllowsCoreThreadTimeOut() |
このプールでコア スレッドがタイムアウトし、keepAlive 時間内にタスクが到着しなかった場合は終了できる場合は true を返します。新しいタスクが到着したときに必要に応じて置き換えられます。 |
AwaitTermination(Int64, TimeUnit) |
通常は |
AwaitTerminationAsync(Int64, TimeUnit) |
通常は |
BeforeExecute(Thread, IRunnable) |
指定されたスレッドで指定された Runnable を実行する前に呼び出されるメソッド。 |
Clone() |
このオブジェクトのコピーを作成して返します。 (継承元 Object) |
Dispose() |
通常は |
Dispose(Boolean) |
通常は |
Equals(Object) |
他のオブジェクトがこのオブジェクトと "等しい" かどうかを示します。 (継承元 Object) |
Execute(IRunnable) |
将来、特定のタスクを実行します。 |
GetHashCode() |
オブジェクトのハッシュ コード値を返します。 (継承元 Object) |
GetKeepAliveTime(TimeUnit) |
スレッドのキープアライブ時間を返します。これは、スレッドが終了するまでアイドル状態のままになる可能性がある時間です。 |
InvokeAll(ICollection) |
通常は |
InvokeAll(ICollection, Int64, TimeUnit) |
通常は |
InvokeAny(ICollection) |
通常は |
InvokeAny(ICollection, Int64, TimeUnit) |
通常は |
JavaFinalize() |
オブジェクトへの参照がなくなったとガベージ コレクションが判断したときに、オブジェクトのガベージ コレクターによって呼び出されます。 (継承元 Object) |
NewTaskFor(ICallable) |
指定された |
NewTaskFor(IRunnable, Object) |
指定された |
Notify() |
このオブジェクトのモニターで待機している 1 つのスレッドを起動します。 (継承元 Object) |
NotifyAll() |
このオブジェクトのモニターで待機しているすべてのスレッドを起動します。 (継承元 Object) |
PrestartAllCoreThreads() |
すべてのコア スレッドを開始し、作業を idly 待機します。 |
PrestartCoreThread() |
コア スレッドを開始し、作業を idly 待機します。 |
Purge() |
取り消されたすべての |
Remove(IRunnable) |
Executor の内部キューが存在する場合は、このタスクを削除するため、まだ開始されていない場合は実行されません。 |
SetHandle(IntPtr, JniHandleOwnership) |
Handle プロパティを設定します。 (継承元 Object) |
SetKeepAliveTime(Int64, TimeUnit) |
スレッドのキープアライブ時間を設定します。これは、スレッドが終了するまでアイドル状態のままになる時間です。 |
Shutdown() |
以前に送信されたタスクが実行される順序どおりにシャットダウンを開始しますが、新しいタスクは受け入れされません。 |
ShutdownNow() |
アクティブに実行されているすべてのタスクを停止し、待機中のタスクの処理を停止し、実行を待機していたタスクの一覧を返します。 |
Submit(ICallable) |
通常は |
Submit(IRunnable) |
実行可能タスクを送信し、そのタスクを表す Future を返します。 (継承元 AbstractExecutorService) |
Submit(IRunnable, Object) |
通常は |
Terminated() |
Executor が終了したときに呼び出されるメソッド。 |
ToArray<T>() |
通常は |
ToString() |
オブジェクトの文字列形式を返します。 (継承元 Object) |
UnregisterFromRuntime() |
通常は |
Wait() |
現在のスレッドが起動するまで待機します。通常<は、通知</em> または>< em 中断</em によって待機します>。> (継承元 Object) |
Wait(Int64) |
現在のスレッドが起動するまで待機します。通常<は、通知></em> または <>em 中断</em>、または特定のリアルタイムが経過するまで待機します。 (継承元 Object) |
Wait(Int64, Int32) |
現在のスレッドが起動するまで待機します。通常<は、通知></em> または <>em 中断</em>、または特定のリアルタイムが経過するまで待機します。 (継承元 Object) |
明示的なインターフェイスの実装
IJavaPeerable.Disposed() |
通常は |
IJavaPeerable.DisposeUnlessReferenced() |
通常は |
IJavaPeerable.Finalized() |
通常は |
IJavaPeerable.JniManagedPeerState |
通常は |
IJavaPeerable.SetJniIdentityHashCode(Int32) |
通常は |
IJavaPeerable.SetJniManagedPeerState(JniManagedPeerStates) |
通常は |
IJavaPeerable.SetPeerReference(JniObjectReference) |
通常は |
拡張メソッド
JavaCast<TResult>(IJavaObject) |
Android ランタイムチェック型変換を実行します。 |
JavaCast<TResult>(IJavaObject) |
通常は |
GetJniTypeName(IJavaPeerable) |
通常は |
AwaitTerminationAsync(IExecutorService, Int64, TimeUnit) |
通常は |
InvokeAnyAsync(IExecutorService, ICollection) |
通常は |
InvokeAnyAsync(IExecutorService, ICollection, Int64, TimeUnit) |
通常は |