スレッドプールは、タスクを並行して収集するための実用的なツールです。アプリケーションの並列化に適したマルチコアアーキテクチャの導入により、スレッドプールの役割はますます明らかになりつつあります。 ThreadPoolexecutorクラスおよびその他の補助クラスを通じて、Java 5はこのフレームワークを新しい並行性サポートセクションとして紹介しました。
ThreadPoolexecutorフレームワークは柔軟で強力です。ユーザー固有の構成をサポートし、完全なキューを処理するための関連するフックと飽和ポリシーを提供します。
Javaスレッドプールは、提出されたタスクをワークキューに最初に配置し、作業キューからそれらを取得します(Synchronousqueueは、プロデューサーからワークスレッドに直接送信されます)。次に、動作するキューには2つの実装戦略があります。無制限のキューの飽和に問題はありませんが、問題は、リクエストが高くなり続けると、作業キューに巧みに追加され、メモリやその他のリソースがオーバーフローまたは排気を引き起こす可能性があることです。境界のあるキューは、高い負荷によって引き起こされるメモリの疲労を引き起こしませんが、作業キューがいっぱいになったときに新しく提出されたタスクを管理する方法の問題があります。これは、スレッドプールの動作キュー飽和戦略が解決する必要がある問題です。
飽和戦略は、中止戦略、Callerruns戦略、廃棄戦略、およびDidardolds戦略に分かれています。
より良い理解のために、私は小さな例を書きました。
package concurrency.pool;import java.util.concurrent.LinkedBlockingDequ;import java.util.concurrent.RejectedExecutionHandler;import java.util.concurrent.ThreadPoolExecutor;import java.util.concurrent.TimeUnit;public class SaturationPolicy {/** * When the thread pool work queue is full, it will behave underさまざまな飽和ポリシー* @paramハンドラースレッドプールワークキュー飽和ポリシー*/public static voidポリシー(拒否Executionhandler Handler){// 2つの基本的なスレッドがあり、スレッドの最大数は3、および作業キュー容量は5です。スレッドプールエクセクターexec =新しいスレッドプールエクセクター(2,3,3,3,0L、タイムナイトマリスセコンlinkedblockingdeque <>(5)); if(handler!= null){exec.setrejectedexecutionhandler(handler); // set飽和ポリシー} for threadpoolexecutor.abortpolicy()); // policy((new shoodpoolexecutor.callerrunspolicy()); // policy(new SthreadPoolexecutor.DiscardPolicy()); //ポリシー(新しいThreadPoolexcutor.DiscardOldestPolicy();} 0; // task id public task(){id = ++ count;}@override public void run(){try {timeunit.seconds.sleep(3); // 3秒間スリープ} catch(system.err.println( "スレッドが中断された" + e.getmessage( " + e.getmessage()); " + thread.currentThread()。getName() +" execution reftelement ");}}}}作業キューがいっぱいの場合、さまざまな戦略が次のように処理されます。
1.アボートポリシー:デフォルトのポリシー。新しいタスクが送信されると、未確認の例外が直接スローされます。例外は、発信者が捕まえることができます。
メイン関数に次のコードを追加します。
ポリシー(new threadPoolexecutor.abortPolicy());
操作結果は次のとおりです。
プログラムは拒否ExecutionExceptionをスローし、合計8つのタスクが実行されます(スレッドプールは最初に3つのタスクを実行でき、5つのキューが作業キューに保存されます)。作業キューがいっぱいになった場合、例外が直接スローされ、JVMが終了しません(今の理由はわかりません)。タスクを実行するすべてのスレッドは、スレッドプールのスレッドであることがわかります。
2。Callerruns戦略:調整メカニズムの場合、タスクを放棄したり例外を投げたりすることも、発信者に戻ります。新しいタスクは、スレッドプールではなく、エクセクターを呼び出すスレッドで実行されます。
メイン関数で実行します:
ポリシー(新しいthreadpoolexecutor.callerrunspolicy()));
実行結果
すべてのタスクが実行され、2つ(10-3 -5)のタスクがメインスレッドで正常に実行され、8つのタスクがスレッドプールのスレッドによって実行されます。
3.ディスカード戦略:新しく提出されたタスクは放棄されます。
メイン関数で実行します
ポリシー(new threadPoolexecutor.discardPolicy());
上記の結果は、例外がスローされず、後で提出された2つの新しいタスクが破棄され、最初の8つの(3+5)タスクのみが処理され、JVMが出ることを示しています。
4. DiscardOldest Strategy:キューは「チームのヘッド」のタスクであり、新しいタスクを提出しようとします。 (優先キューとしての作業キューシナリオには適していません)
メイン関数で次の方法を実行します
ポリシー(新しいthreadpoolexecutor.discardoldestpolicy());
実行結果:合計8つのタスクが実行されています。プログラムは終了します。追加されたタスクは後で9と10で、以前のタスク3と4は破棄されます。
要約します
上記は、Javaスレッドプールワークキュー飽和戦略のコード例に関するこの記事の内容全体です。私はそれが誰にでも役立つことを願っています。欠点がある場合は、それを指摘するためにメッセージを残してください。このサイトへのご支援をありがとうございました。