マルチスレッド設計モード-Thread Pool(スレッドプール)モード
5161 ワード
これらは私が最近見た『Java実戦ガイドマルチスレッドプログラミング(設計モード編)』に基づいて整理されています.
パターン名
Thread Poolモード
パターン解決の問題
1つのシステム内のスレッドは、処理するタスクに対して、常に非常に限られたリソースがあり、スレッドは、タスクの実行にCPU時間やメモリなどのリソースを消費するだけでなく、スレッドオブジェクト自体やスレッドに必要な呼び出しスタックにもメモリを消費する.また、Javaでスレッドを作成することは、JVMがホストオペレーティングシステムに依存するローカルスレッドを作成することを意味することが多い.したがって、各タスクまたは各タスクの実行のためにスレッドを作成することは、通常、贅沢で現実的ではないことです.
解決策
比較的一般的な方法は、一定数のスレッドを服用し、これらのスレッドによって絶えず発生するタスクを実行することです.ThreadPoolクラスは、タスクの受信と格納、および作業者スレッドの生命管理を担当します.submitは、クライアントコードがスレッドプールにタスクをコミットするように呼び出すタスクを受信するために使用されます.shutdownは、スレッドプールが外部に提供するサービスPromiseを閉じて、対応するタスクの実行結果の証明書オブジェクトを取得することができます.setResuleは、対応するタスクの実行結果の実行結果を取得し、getResuleは、対応するタスクの実行結果の実行結果を設定します.WorkQueueワークキューは、タスクのキャッシュを実現します.Enqueueはタスクをキューに格納し、dequeueはキューからタスクを取り出します.WorkerThreadは、タスクの実行を担当するスレッドです.runはワークキューからタスク実行を1つずつ取り出し,runTaskは作成したタスクを実行する.
Created with Raphaël 2.1.0 client client threadPool threadPool workQueue workQueue promist promist 1submit() 2enqueue() 3 4creat 5
サンプルコード
あるシステムは、ユーザがいくつかの重要な操作を実行する前に、認証コードを入力するように要求し、認証コードはランダムな数字であり、システムのサーバ側コードによって生成され、メールを通じてユーザに送信される.
モデルの評価と考慮
ThreadPoolモードは、一定数の作業者スレッドを服用することによって、絶えず提出されるタスクを実行し、スレッドという限られた2つの高価なリソースを節約する.このモードには、次のいくつかのメリットがあります.スレッド作成のオーバーヘッドを相殺し、応答性を向上させる には、作業者スレッドのライフサイクル管理 がカプセル化されています.廃棄スレッドのオーバーヘッドを削減 このモデルにはこれらのメリットがありますが、いくつかのリスクと問題があります.ワークキューの選択:通常3つのキュー方式があり、境界キュー(BoundedQueue)ワークキュー自体はスレッドプールで実行を待つタスクの数を制限しないが、ワークキューで実際に収容できるタスクはタスク自体のリソースの使用状況に依存する.境界キュー(UnboundQueue)ワークキューはスレッドプールで大物を待つ数を制限する.一定の成都で資源の消費を制限することができる.直接受け渡しキュー(SymchrinousQueue)は、バッファ内でタスクをコミットする際に呼び出されるワークキューの非ブロック式のキューメソッドではないので、キューを待つことなく、新しいスレッドがキューに失敗したタスクを処理します. スレッドプールサイズ調整:リソースを浪費しすぎて、リソースを十分に利用できないため、スレッドプールのサイズは、スレッドプールが処理するタスクの特性、システムリソース、およびタスクロックが使用する希少なリソースの状況に依存します. スレッドプール監視:スレッドプールの大きさ、ワークキューの容量、スレッドの空き時間制限これらの熟知したデバッグプロセスは、ThreadPoolExecutorクラスのデバッグを容易にするために監視するプログラムが必要です. スレッドの漏洩:スレッドプール内のワーカースレッドが予期せぬ終了し、スレッドプールで実際に使用可能なワーカースレッドが減少します.スレッドオブジェクトのrunメソッドの例外処理がRuntimeExceptionとErrorをキャプチャしていないため、runメソッドが予期せずに返され、対応するスレッドが予期せずに終了します.したがって、対応する例外を注入してキャプチャします.しかし、スレッドが外部リソースを要求する必要があり、外部リソースの要求に時間制限がない場合、スレッドは実際に漏洩している可能性があることに注意する必要があります. 信頼性とスレッドプール飽和処理ポリシー:ワークキューの選択はスレッドサイズの需要変化に対して処理方式がないため、スレッド飽和処理ポリシーが必要である. デッドロック:スレッド要求のようなリソースがデッドロックを形成する可能性があります. スレッドプール空きスレッドクリーンアップ:タスク処理を長時間行わなかったスレッドはシステムリソースの浪費であるため、対応する処理コードが必要である.
パターン名
Thread Poolモード
パターン解決の問題
1つのシステム内のスレッドは、処理するタスクに対して、常に非常に限られたリソースがあり、スレッドは、タスクの実行にCPU時間やメモリなどのリソースを消費するだけでなく、スレッドオブジェクト自体やスレッドに必要な呼び出しスタックにもメモリを消費する.また、Javaでスレッドを作成することは、JVMがホストオペレーティングシステムに依存するローカルスレッドを作成することを意味することが多い.したがって、各タスクまたは各タスクの実行のためにスレッドを作成することは、通常、贅沢で現実的ではないことです.
解決策
比較的一般的な方法は、一定数のスレッドを服用し、これらのスレッドによって絶えず発生するタスクを実行することです.ThreadPoolクラスは、タスクの受信と格納、および作業者スレッドの生命管理を担当します.submitは、クライアントコードがスレッドプールにタスクをコミットするように呼び出すタスクを受信するために使用されます.shutdownは、スレッドプールが外部に提供するサービスPromiseを閉じて、対応するタスクの実行結果の証明書オブジェクトを取得することができます.setResuleは、対応するタスクの実行結果の実行結果を取得し、getResuleは、対応するタスクの実行結果の実行結果を設定します.WorkQueueワークキューは、タスクのキャッシュを実現します.Enqueueはタスクをキューに格納し、dequeueはキューからタスクを取り出します.WorkerThreadは、タスクの実行を担当するスレッドです.runはワークキューからタスク実行を1つずつ取り出し,runTaskは作成したタスクを実行する.
Created with Raphaël 2.1.0 client client threadPool threadPool workQueue workQueue promist promist 1submit() 2enqueue() 3 4creat 5
サンプルコード
あるシステムは、ユーザがいくつかの重要な操作を実行する前に、認証コードを入力するように要求し、認証コードはランダムな数字であり、システムのサーバ側コードによって生成され、メールを通じてユーザに送信される.
public class SmsVerficationCodeSender {
private static final ExecutorService EXECUTOR = new ThreadPoolExecutor(1,
Runtime.getRuntime().availableProcessors(),60,TimeUnit.SECONDS,
new SynchronousQueue(),new ThreadFactory(){
@Override
public Thread newThread(Runnable r){
thread t = new Thread(r,"VerfCodeSender");
t.setDaemon(true);
return t;
}
});
//
public void sendVerificationSme(final String misisdn){
Runnable task = new Runnable(){
@Override
public void run(){
//
int verificationCode = ThreadSpeciticSecureRandom.INSANCE
.nextInt(999999);
DecimalFormat df = new DecimalFormat("000000");
String txtVerCode = df.format(verificationCode);
//
sendSms(misisdn,txtVerCode);
}
};
EXECUTOR.submit(task);
}
private void sendSms(String msisdn,String verificationCode){
System.out.println("Sending verification code " + verificationCode + " to "
+ msisdn);
//
}
}
モデルの評価と考慮
ThreadPoolモードは、一定数の作業者スレッドを服用することによって、絶えず提出されるタスクを実行し、スレッドという限られた2つの高価なリソースを節約する.このモードには、次のいくつかのメリットがあります.