『Java同時プログラミング実戦』-7
2808 ワード
スレッドプールの使用
8.1タスクと実行ポリシーの間の隠れた結合
すべてのタスクではありません.一部のタスクでは、次のような実行ポリシーを明確に指定する必要があります.依存タスク スレッドクローズドメカニズムを使用するタスク. は、時間に敏感なタスクに対応します. ThreadLocalを使用するタスク いくつかのタスクでは、特定の実行ポリシーを所有または排除する必要があります.一部のタスクが他のタスクに依存している場合、スレッドプールが十分に大きいことが要求され、依存タスクが待機キューに入れられたり拒否されたりしないことを確認し、スレッド閉鎖メカニズムを採用したタスクはシリアルで実行する必要があります.これらの要件をドキュメントに書き込むことで、将来のコード・メンテナンス担当者は、適切でない実行ポリシーを使用してセキュリティやアクティビティを破壊することはありません.
8.1.1スレッド飢餓デッドロック
依存性のあるExecutorタスクがコミットされるたびに、スレッドの「飢餓」デッドロックが発生する可能性があることを明確に認識するために、スレッドプールのサイズ制限または構成制限をコードまたは構成Executorのプロファイルに記録する必要があります.
8.1.2実行時間の長いタスク
タスクのブロック時間が長すぎると、デッドロックが発生しなくてもスレッドプールの応答性が悪くなります.
タスクを決定してリソースを待つ時間は、無制限に待つのではなく、実行時間が長いタスクの影響を緩和します.
8.2スレッドプールのサイズ設定
通常、スレッドプールのサイズを正しく設定します(CPUがn個あると仮定します):計算密集型:2 n+1 I/O密集型:2 n 8.3 ThreadPoolExecutorの構成
ThreadPoolExecutorの汎用コンストラクタ
スレッドの作成と破棄
基本サイズ(Core Poll Size)は、スレッドプールのターゲットサイズです.つまり、タスク実行時のスレッドプールのサイズがなく、ワークキューがいっぱいになった場合にのみ、この数を超えるスレッドが作成されます.
スレッドプールの最大サイズ(maximumPoolSize)は、同時にアクティブにできるスレッドの数の上限を表します.スレッドのアイドルイベントが生存時間を超えた場合、回収可能としてマークされ、スレッドプールの現在のサイズがほぼ大きい場合、このスレッドは終了します.
キュータスクの管理
ThreadPoolExecutorでは、実行待ちのタスクを保存するためにBlockingQueueを提供できます.基本的なタスクキュー方法は,無境界キュー,有界キュー,同期遷移の3つである.
Executorでは、newCachedThreadPoolファクトリメソッドの場合、固定サイズのスレッドよりも優れたキュー性能を提供することができます.リソース管理の要件を満たすために現在のタスクの数を制限する必要がある場合、ネットワーク・クライアントの要求を受け入れるサーバ・アプリケーションで制限しないと、オーバーロードの問題が発生しやすいように、固定サイズのスレッド・プールを選択できます.
8.3.3飽和戦略
各RejectedExecutionHandlerの実装には、不要な飽和ポリシーが含まれています. Abortポリシー:デフォルトのポリシーです.新しいタスクの発行時に、呼び出し元によって取得できる、チェックされていない例外RejectedExecutionExceptionが直接放出されます. CallerRunPolicyは調整メカニズムであり、タスクも例外も捨てず、一部のタスクを呼び出し元に戻します.スレッドプールのスレッドで新しいタスクを実行するのではなく、exectorを呼び出すスレッドで新しいタスクを実行します. Discardポリシー:新しくコミットされたタスクは破棄されます.DiscardOldestポリシー:キューに「キューヘッダ」のタスクがあり、新しいタスクをコミットしようとします.(優先キューシーンとしてワークキューには適していません). 8.3.4スレッドファクトリ
8.4拡張ThreadPoolExecutor
例:スレッドプールに統計を追加する
8.5再帰アルゴリズムの並列化
例:パズルフレーム
同時に実行されるタスクの場合、EXecutorフレームワークは強力で柔軟なフレームワークです.スレッドの作成やスレッドを閉じるポリシー、キュー・タスクを処理するポリシー、マルチタスクを処理するポリシーなど、調整可能なオプションが多数用意されており、動作を拡張するためのフック・メソッドがいくつか用意されています.しかし、ほとんどの強力なフレームワークと同様に、パラメータの設定がうまく機能しないものもあり、特定の実行ポリシーが必要なタスクもありますが、パラメータの組み合わせによっては奇妙な結果が発生する可能性があります.
8.1タスクと実行ポリシーの間の隠れた結合
すべてのタスクではありません.一部のタスクでは、次のような実行ポリシーを明確に指定する必要があります.
8.1.1スレッド飢餓デッドロック
依存性のあるExecutorタスクがコミットされるたびに、スレッドの「飢餓」デッドロックが発生する可能性があることを明確に認識するために、スレッドプールのサイズ制限または構成制限をコードまたは構成Executorのプロファイルに記録する必要があります.
8.1.2実行時間の長いタスク
タスクのブロック時間が長すぎると、デッドロックが発生しなくてもスレッドプールの応答性が悪くなります.
タスクを決定してリソースを待つ時間は、無制限に待つのではなく、実行時間が長いタスクの影響を緩和します.
8.2スレッドプールのサイズ設定
通常、スレッドプールのサイズを正しく設定します(CPUがn個あると仮定します):
ThreadPoolExecutorの汎用コンストラクタ
public ThreadPoolExecutor(int corePoolSize,
int maximumPollSize,
long keepAliveTime,
BlockingQueue workQueue,
ThreadFactory threadFactory,
RejectedExecutionHandler handler)
{ ... }
スレッドの作成と破棄
基本サイズ(Core Poll Size)は、スレッドプールのターゲットサイズです.つまり、タスク実行時のスレッドプールのサイズがなく、ワークキューがいっぱいになった場合にのみ、この数を超えるスレッドが作成されます.
スレッドプールの最大サイズ(maximumPoolSize)は、同時にアクティブにできるスレッドの数の上限を表します.スレッドのアイドルイベントが生存時間を超えた場合、回収可能としてマークされ、スレッドプールの現在のサイズがほぼ大きい場合、このスレッドは終了します.
キュータスクの管理
ThreadPoolExecutorでは、実行待ちのタスクを保存するためにBlockingQueueを提供できます.基本的なタスクキュー方法は,無境界キュー,有界キュー,同期遷移の3つである.
Executorでは、newCachedThreadPoolファクトリメソッドの場合、固定サイズのスレッドよりも優れたキュー性能を提供することができます.リソース管理の要件を満たすために現在のタスクの数を制限する必要がある場合、ネットワーク・クライアントの要求を受け入れるサーバ・アプリケーションで制限しないと、オーバーロードの問題が発生しやすいように、固定サイズのスレッド・プールを選択できます.
8.3.3飽和戦略
各RejectedExecutionHandlerの実装には、不要な飽和ポリシーが含まれています.
8.4拡張ThreadPoolExecutor
例:スレッドプールに統計を追加する
8.5再帰アルゴリズムの並列化
例:パズルフレーム
同時に実行されるタスクの場合、EXecutorフレームワークは強力で柔軟なフレームワークです.スレッドの作成やスレッドを閉じるポリシー、キュー・タスクを処理するポリシー、マルチタスクを処理するポリシーなど、調整可能なオプションが多数用意されており、動作を拡張するためのフック・メソッドがいくつか用意されています.しかし、ほとんどの強力なフレームワークと同様に、パラメータの設定がうまく機能しないものもあり、特定の実行ポリシーが必要なタスクもありますが、パラメータの組み合わせによっては奇妙な結果が発生する可能性があります.