#ThreadPool スレッド プール
java 基本チュートリアル)
1. スレッド プールの利点
1.1. はじめに
データベース スレッド プールと同様に、データベース接続プールがない場合は、データベース接続プールを使用して接続プールを取得するたびに new が必要になります。接続と解放を繰り返すとシステムリソースが大量に消費されますが、データベース接続プールを利用し、プールから直接接続プールを取得することができます。 同様に、スレッド プールが存在する前は、new Thread.start() を通じてスレッドを取得していましたが、現在では new が必要ないため、再利用を実現し、システムをより効率的にすることができます。
1.2. スレッド プールを使用する理由
例:スレッド プールの利点:
スレッド プールは、実行中のスレッドの数を制御し、実行中にタスクをキューに入れるだけで済みます。処理中です。スレッドの作成後にこれらのタスクを開始します。スレッドの数が最大数を超えると、超過したスレッドはキューに入れられ、他のスレッドの実行が完了するのを待ち、その後タスクをキューから取り出して実行します。 。
その主な機能は次のとおりです。2.1. アーキテクチャの説明
Executorフレームワークとは何ですか?
Java Doc では次のように説明されています
送信された実行可能タスクを実行するオブジェクト。このインターフェイスは、タスクの送信を各タスクの仕組みから切り離す方法を提供します。スレッドの使用、スケジュール設定などの詳細を含む実行。通常、スレッドを明示的に作成する代わりにエグゼキュータが使用されます。
送信された実行可能タスクを実行するオブジェクト。このインターフェイスは、タスクを送信するメカニズムと、スレッドの使用状況、スケジュールなどの詳細を含む各タスクの実行方法を提供します。スレッドを明示的に作成する代わりに Executor を使用するのが一般的です。 Java のスレッド プールは、Executor、Executors、ExecutorService、および ThreadPoolExecutor クラスを使用する Executor フレームワークを通じて実装されます。
私たちが一般的に使用するインターフェイスは ExecutorService サブインターフェイスです、Executor はスレッドのツール クラスです (配列 Array に似たツール クラス、コレクションのツール クラス Collections)。 ThreadPoolExecutor はこれらのクラスの焦点です。 ThreadPoolExecutor スレッド プールは、補助ツール クラス Executors を通じて取得できます。
各クラスの詳細については、次のとおりです。
ExecutorService は、Executor 実装クラスの最も直接的なインターフェイスである Executor の動作を追加します。このインターフェイスの定義Executor のサービスを提供します
Executor スレッド プール ファクトリ クラスは、スレッド プールを作成するための一連のファクトリ メソッドを提供します。返されたスレッド プールはすべて、
ScheduledExecutorService: スケジュールされたスケジューリング インターフェイスを実装します。 AbstractExecutorService 実行フレームワークの抽象クラス。
ThreadPoolExecutor は、JDK のスレッド プールの特定の実装です。一般的に使用されるさまざまなスレッド プールは、このクラスに基づいて実装されます。
##2.2.1.newFixedThreadPool(int) メソッド
Exectors.newFixedThreadPool(int) -->長期実行における優れたパフォーマンスタスクを実行するには、スレッド プールを作成します。プールには N 個の固定スレッドと固定数のスレッドがあります。
public static void main(String[] args) { //一池5个受理线程,类似一个银行5个受理窗口。不管你现在多少个线程,都只有5个 ExecutorService threadPool=Executors.newFixedThreadPool(5); try { //模拟有10个顾客过来银行办理业务,目前池子里面有5个工作人员提供服务。 for(int i=1;i{ System.out.println(Thread.currentThread().getName()+"\t 办理业务"); }); } } catch (Exception e) { // TODO: handle exception }finally{ threadPool.shutdown(); } }
実行結果が確認できます。プールには 5 つのスレッドがあり、これは外部サービスを提供し、ビジネスを処理する 5 人のスタッフ メンバーに相当します。写真では、窓口 1 が 2 回の業務を行っており、銀行の受付窓口は複数回再利用できます。必ずしも全員が 2 回処理する必要はありませんが、より速く処理した人がより多く処理することになります。
スレッドの実行中に 400 ミリ秒の遅延を追加すると、その影響が確認できます。
public static void main(String[] args) { //一池5个受理线程,类似一个银行5个受理窗口。不管你现在多少个线程,都只有5个 ExecutorService threadPool=Executors.newFixedThreadPool(5); try { //模拟有10个顾客过来银行办理业务,目前池子里面有5个工作人员提供服务。 for(int i=1;i{ System.out.println(Thread.currentThread().getName()+"\t 办理业务"); }); try { TimeUnit.MILLISECONDS.sleep(400); } catch (Exception e) { // TODO: handle exception e.printStackTrace(); } } } catch (Exception e) { // TODO: handle exception }finally{ threadPool.shutdown(); } }
これは、ネットワークが混雑しているか、ビジネスが比較的遅いことを意味します。スレッド プールによって処理されるビジネス タスクの分散は比較的均等です。
Exectors.newSingleThreadExector()–>1 つのタスク、1 つのプール、1 つのスレッドの実行
public static void main(String[] args) { //一池一个工作线程,类似一个银行有1个受理窗口 ExecutorService threadPool=Executors.newSingleThreadExecutor(); try { //模拟有10个顾客过来银行办理业务 for(int i=1;i{ System.out.println(Thread.currentThread().getName()+"\t 办理业务"); }); } } catch (Exception e) { // TODO: handle exception }finally{ threadPool.shutdown(); } }
Exectors.newCachedThreadPool()–>多くの短期的な非同期タスクを実行します。スレッド プールは必要に応じて新しいスレッドを作成しますが、以前は構築されたスレッド 利用可能な場合は再利用されます。拡張できるし、強いときは強い。 n 個のスレッドのプール、拡張可能、スケーラブル、キャッシュ キャッシュとは、
では、プールの数はどのくらいに設定すればよいでしょうか? 銀行の窓口が 1 つしかない場合、人が多すぎると混雑してしまいます。銀行に窓口がたくさんあるのに来る人が少ないと、資源の無駄遣いのように思えてしまいます。では、どうすれば合理的な取り決めができるのでしょうか?これには、拡張可能でスケーラブルな newCachedThreadPool() メソッドを使用する必要があります。
public static void main(String[] args) { //一池一个工作线程,类似一个银行有n个受理窗口 ExecutorService threadPool=Executors.newCachedThreadPool(); try { //模拟有10个顾客过来银行办理业务 for(int i=1;i{ System.out.println(Thread.currentThread().getName()+"\t 办理业务"); }); } } catch (Exception e) { // TODO: handle exception }finally{ threadPool.shutdown(); } }
public static void main(String[] args) { //一池一个工作线程,类似一个银行有n个受理窗口 ExecutorService threadPool=Executors.newCachedThreadPool(); try { //模拟有10个顾客过来银行办理业务 for(int i=1;i{ System.out.println(Thread.currentThread().getName()+"\t 办理业务"); }); } } catch (Exception e) { // TODO: handle exception }finally{ threadPool.shutdown(); } }
3。 ThreadPoolExecutor の
##newFixedThreadPool の基礎となるソース コードpublic static ExecutorService newFixedThreadPool(int nThreads) { return new ThreadPoolExecutor(nThreads, nThreads, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<runnable>()); }</runnable>ご覧のとおり、基礎となるパラメータには LinkedBlockingQueue ブロッキング キューが含まれています。 newSingleThreadExecutor の基礎となるソース コード
public static ExecutorService newSingleThreadExecutor() { return new FinalizableDelegatedExecutorService (new ThreadPoolExecutor(1, 1, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<runnable>())); }</runnable>newCachedThreadPool の基礎となるソース コード
public static ExecutorService newCachedThreadPool() { return new ThreadPoolExecutor(0, Integer.MAX_VALUE, 60L, TimeUnit.SECONDS, new SynchronousQueue<runnable>()); }</runnable>SynchronousQueue このブロッキング キューはブロッキング キューの単一バージョンであり、ブロッキング キューの容量は 1 です。 .
これら 3 つのメソッドは実際にはすべて、ThreadPoolExecutor のオブジェクトであるオブジェクトを返します。
4. スレッド プールの 7 つの重要なパラメータ
ThreadPoolExecutor のコンストラクタpublic ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<runnable> workQueue, ThreadFactory threadFactory, RejectedExecutionHandler handler) { if (corePoolSize 上記の int corePoolSize、int minimumPoolSize、long keepAliveTime、TimeUnit Unit 、 BlockingQueue workQueue、ThreadFactory threadFactory、 <p> RejectedExecutionHandler ハンドラーは 7 つのスレッド パラメーターです <br> 上記は、7 つのパラメーターを持つ ThreadPoolExecutor クラスの構築メソッドです。 <br></p>1) <p>corePoolSize: threadプール <strong> 単位の常駐コア スレッドの数。コア数と呼ばれます。 </strong> たとえば、スレッド プールを銀行の支店として扱うことができます。銀行が営業している限り、少なくとも 1 人の当直者が存在する必要があります。これを常駐コア スレッドの数と呼びます。たとえば、銀行の 5 つの支店すべてが月曜日から金曜日まで営業している場合、月曜日から金曜日までの常駐コア スレッドの数は 5 になります。今日は業務がそれほど頻繁ではなく、ウィンドウが 1 の場合、常駐コア スレッドの数は 5 になります。今日は 1 <br></p>2) <p>maxImumPoolSize: スレッド プール内で同時に実行できるスレッドの最大数。この値は 1<strong></strong></p> 以上である必要があります。 3) <p>keepAliveTime: 超過アイドル時間 スレッドの生存時間 現在のプール内のスレッド数が corePoolSize を超えた場合、アイドル時間が keepAliveTime に達すると、超過スレッドは corePoolSize が残るまで破棄されます。 ## スレッドプールに常駐スレッドがあり、上限がある場合 スレッド数は通常は常駐していることを意味します 作業が緊迫している場合は最大スレッド数まで拡張されます ビジネスが落ちた場合は、余剰アイドルスレッドの生存時間を30秒に設定するなど、30秒超過がない場合は、リクエスト時にウィンドウを閉じる銀行もありますので、拡張するだけでなく縮小することもできます。 <strong></strong>4) <br>単位: keepAliveTime の単位</p> <p> 単位: 秒、ミリ秒、マイクロ秒。 <strong></strong><br>5) workQueue: タスク キュー、送信されたが実行されていないタスク </p> <p> これは銀行などのブロッキング キューであり、受け入れウィンドウが 3 つしかありません。そして4人が来ます。この阻止列は銀行の待機場所であり、一度来た顧客はそこから出ることはできません。ウィンドウの数によって、同時スレッドの数が制御されます。 <strong></strong>6) <br>threadFactory: スレッド プール内に作業スレッドを生成するスレッド ファクトリを表します。スレッドの作成に使用されます。通常、デフォルトは </p> <p> です。スレッドはすべて均一に作成されます。 。スレッド プールには、スレッド プール ファクトリによって生成された新しいスレッドがあります。 <strong></strong><br>7) ハンドラー: 拒否戦略。現在のキューがいっぱいで、作業スレッドがスレッド プール内の最大スレッド数以上である場合に、実行可能なリクエストの実行戦略を拒否する方法を示します。 (最大プールサイズ)</p> <p></p> <p>たとえば、今日は銀行の顧客の流れがピークで、3 つの窓口はすべて満席で、待合室も満席です。安全ではないからといって採用を続けるという選択はせず、丁重にお断りすることにしました。 </p> <p>次のセクションでは、スレッド プールの基本的な動作原理を紹介します。</p> <blockquote><p><strong>関連学習の推奨事項: </strong><a href="https://www.php.cn/java/base/" target="_blank"><strong>Java の基礎</strong></a> </p></blockquote></runnable>
以上がJava が ThreadPool スレッド プールについて説明するの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。