アートのJava並行プログラミング(XII) - スレッドプール

スレッドプールを使用するメリット

  • 資源の損失を低減させますスレッドの作成と破壊のオーバーヘッドを削減する、作成されたスレッドを再使用します。
  • 応答速度を向上させますタスクが来ると、作成されたスレッドは、直前に作成されたタスクスレッドの実装を待たずに、新しいタスクを処理することができます。
  • スレッドを簡単に管理スレッドは希少資源である、システムの安定性を減らすことがあまりにも多くのスレッドを作成し、作成したスレッドの数、およびその監視、管理、チューニングを制御することができますスレッドプールは、システムの安定性を向上させます。

スレッドプールのプロセスフロー

  • スレッドプール内のスレッドの数は、基本的なスレッドの数よりも少ない場合1.新しいタスクが(フリースレッドプールのスレッドがある場合でも、この時間は、だけでなく、新しいスレッドを作成するために)新しいタスクを処理する新しいスレッドを作成し、来る;逆に、次のステップ。
  • スレッドプール内のスレッドの数は、実質的により大きいかまたはスレッドの数に等しいながら新しいタスクの到着は、新しいタスクが処理されるのを待ってブロックされたキューに追加される2。キューをブロックした後、次のステップがいっぱいです。
  • 3.キューがいっぱいになると、新しいタスクが来ると、タスクを実行するための新しいスレッドを作成します。スレッドプールのスレッドは、スレッドの最大数(もはやスレッドを作成することができることを意味する)、次のステップに到達した場合。
  • 4.タスク飽和戦略で扱います。

スレッドプールを使用します

スレッドプールを作成します。

new ThreadPoolExecutor(corePoolSize, maximumPoolSize, keepAliveTime, timeUnit, runnableTaskQueue, handler);
复制代码
  • ●corePoolSize:スレッドの基本的な数は、基本的には、スレッドプールのサイズを表します。スレッドプール内のワーカースレッドの数はスレッドの基本的な数に満たない場合には、常に新しいタスクを処理するための新しいスレッドを作成します。()を呼び出すスレッドプールprestartAllCoreThreads場合は、スレッドプールは、事前にすべての基本的なスレッドを作成されます。
  • ●maximumPoolSize:スレッドの最大数は、スレッドプールを作成することができるスレッドの最大数を表します。タスクキュー内のスレッド数がいっぱいになると、あなたがスレッドの最大数よりも少ないを作成した場合は、スレッドプールは、タスクを実行するための新しいスレッドを作成します。アンバウンド形式のキューのために、値が無効であることに留意すべきです。
  • ●keepAliveTimeが:基本的なスレッドプールのスレッドに加えて、アイドルキープアライブ時間を残りの糸。この時間を超えた後、アイドル状態のスレッドが終了します。
  • ●TIMEUNIT:アライブスレッド単位、1日(日)の必要に応じて単位時間(時間)、分(分)、MS(ミリ秒内)、マイクロ(マイクロ)、NS(ナノ秒)を保ちます。
  • ●runnableTaskQueue:タスクキュー、その任務を行う際に、プール内の基本的なスレッド、新しいタスクが実行されるのを待っているタスクキューに追加されます。キューは、次のオプションがあります。
    • 1.ArrayBlockingQueue:アレイベースのキュー、FIFOを遮断有界。
    • 2.LinkedBlockingQueue:スループットはArrayBlockingQueue、静的ファクトリメソッドExecutors.newFixedThreadPool(より通常高く、無制限のブロッキングキュー、FIFOのリストに基づいて)は、このキューを使用しています。
    • 3.SynchronousQueue:ブロッキングキュー要素が格納されていません。各挿入操作が別のスレッドが削除操作を呼び出すまで待つか、または操作がブロックされた状態にあった挿入する必要があり、スループットがLinkedBlockingQueueよりも通常高く、静的ファクトリメソッドは、このキューを使用Executors.newCachedThreadPool。
    • 4.PriorityBlockingQueue:ブロックされた無線を持つプライオリティキュー。●ハンドラ:飽和戦略、キューとスレッドプールがいっぱいになると、飽和戦略を介して処理のために提出新しいタスク。彩度戦略は次の4つがあります。
      • ①.AbortPolicy:デフォルトポリシーは、役割が直接スローです。
      • ②.CallerRunsPolicy:発信者とタスクを実行するためのスレッドだけ。
      • ③.DiscardOldestPolicy:最近のタスクをキューイングし、現在のタスクを実行して捨てます。
      • ④.DiscardPolicy:無治療、廃棄されました。

スレッドプールにジョブを送信

あなたは、スレッドプールにタスクを提出する2つのメソッドを使用して、それぞれ(実行)と()メソッドを提出することができます。

  • ●実行():タスクは、タスクが正常にプールスレッドで実行されているかどうかを判断することはできません、戻り値を提出する必要はありません。
  • ●提出():必要なリターンミッション値を送信するために使用される、戻り値はオブジェクトの未来型で、オブジェクトは、タスクが正常に実行されているか否かを決定することができ、将来のオブジェクトのこのタイプにより、get()メソッドは、現在のスレッドになるまでブロックすることができタスクが成功すると、メソッドは値を返します。

スレッドプールを閉じます

あなたは、シャットダウン()またはshutdownNowの()メソッドを呼び出すことにより、スレッドプールのスレッドプールを閉じることができます。その原理は、スレッドプールのスレッドを横断することです、その後、一つずつのスレッドの呼び出しは、スレッドを中断するために()メソッドを中断します。これらのアプローチの両方の違いがあります:

  • シャットダウン():このメソッドは、割り込みスレッドは、スレッドがタスクを実行している中断しない、タスクを実行しません。
  • shutdownNowの():このメソッドは、割り込みスレッドは、すべてのタスクを実行したり、一時停止されています。

スレッドプールの合理的な配分

CPU集中型のタスク、IO集約型のタスク、ハイブリッドミッション:タスクの性質はに分けることができます。スレッドプールのタスクの特性を考慮する必要が設​​定します。


  • ●CPU集約型タスク:このようなスレッドプールサイズ構成CPUコア+ 1と小さいスレッドプールを、割り当てるべきなので、頻繁に引き起こされるスイッチングスレッドコンテキストのオーバーヘッドを回避することができます。
  • ●IO集約型のタスクは:IO集約型のタスクレスCPU使用率が、CPUの使用率を向上させることができます多くのスレッドを作成しているため、そのようなスレッドプールサイズに構成CPUコア* 2など、スレッド、最大の可能なプールを割り当てる必要があります率。
  • ●混在タスク:タスクは、タスク以下の完了後に処理するために、2つのスレッド・プール、2分の唯一の実行時間を使用して、その後、人々のCPU集約型のタスクとIO集約型のタスクを分割することができますが、その後、より実行します効率的にシリアル実行。場合は、効率とあまり向上の観点では、党の遅い実装を待つパーティーのより大きな、より高速な実装の間に2つのタスクの実行時間差を。

ThreadPoolExecutor操作機構

ThreadPoolExecutorは、新しいタスクを追加する()メソッドを実行実行すると、以下のように、操作機構は次のようになります。

  • 1.も、アイドル状態のスレッドで、corePoolSizeよりも少ないを実行しているスレッドプールスレッドがタスクを実行するために、新しいスレッドを作成する場合は。
  • スレッドプールで実行中のスレッドがcorePoolSize以上であれば2は、新しいタスクがキューに追加置きます。
  • 3.キューが満杯とタスクを実行するための新しいスレッドを作成し、maximumPoolSize未満を実行しているスレッドの数である場合。
  • 前記キューがいっぱいになるとmaximumPoolSizeを、実行中のスレッドの最大数が飽和ポリシーを実行します。

  • 注意:新しいスレッドを作成するグローバルロック(大きな営業費用)、ThreadPoolExecutor可能グローバルロック取得を避けるために、上記のデザインのアイデアを取るを取得する必要があります。スレッドプール内のスレッドの数が以上corePoolSizeが実行されている場合、一般的に、マルチタスク実行キューのでグローバルロック取得を回避するために、かなり直接的にスレッドを作成するタスクを処理以外に追加されるのを待っています。

おすすめ

転載: juejin.im/post/5d16bc7ee51d45108223fca8