Javaスレッドプール実行プロセス

ユーザースレッド(ULT):スレッドはカーネルサポートなしでユーザープログラムに実装され、オペレーティングシステムコアに依存しません。アプリケーションプロセスはスレッドライブラリを使用して、ユーザースレッドを制御するスレッドを作成、同期、スケジューリング、および管理するための関数を提供します。さらに、ユーザースレッドは、スレッドライブラリを使用するアプリケーションプロセスによって作成および管理され、オペレーティングシステムのコアに依存しません。ユーザーモード/コアモードの切り替えは不要で、速度は高速です。オペレーティングシステムのカーネルは、複数のスレッドが存在する必要があることを認識していません。そのため、1つのスレッドブロックによりプロセス全体がブロックされます。(オペレーティングシステムは、内部で作成された複数のスレッドを認識しません。1つのスレッドが実行されると、オペレーティングシステムは他のユーザースレッドに追加のCPUを割り当てません)

カーネルスレッド(KLT)スレッドのすべての管理操作は、オペレーティングシステムによって完了します。カーネルはスレッドの状態とコンテキスト情報を保存します。スレッドがブロックを引き起こすシステムコールを実行すると、カーネルはプロセスの他のスレッドの実行をスケジュールできます。マルチプロセッサシステムでは、カーネルは同じプロセスに属する複数のスレッドを割り当てて、複数のプロセッサで実行し、プロセス実行の同時実行性を向上させることができます。カーネルはスレッドの作成、スケジューリング、および管理を完了するため、操作はユーザースレッドよりもはるかに低速ですが、プロセスの作成および管理操作よりも高速です。

スレッドプールを使用する理由
スレッドは希少なリソースであり、その作成と破棄は比較的重くリソースを消費する操作であり、Javaスレッドはカーネルスレッドに依存しており、スレッドの作成にはオペレーティングシステムの状態の切り替えが必要です。タスク、スレッドプールはスレッドキャッシュであり、スレッドの割り当て、スケジューリング、および監視を統合します。

スレッドプール実行フロー
ここに画像の説明を挿入

たとえば、現在100個のタスクがあり、スレッドプール内のコアスレッドの数は4、スレッドの最大数は6です。

  1. executeメソッドが実行されると、4つのタスクが直接コアスレッドプールに入り、実行されます。
  2. 残りの94個のタスクがタスクキューに入ります(ArrayBlockingQueueとLinkedBlockingQueueは境界キューですが、LinkedBlockingQueueで十分です。デフォルトはInteger.MAX_VALUEです)。実行を待機しています。
  3. キューがいっぱいになると、残りのタスクが非コアスレッドプールで実行されます。
  4. キューと非コアスレッドプールの両方が満たされると、拒否戦略が実装されます。
    • ThreadPoolExecutor.AbortPolicy()— java.util.concurrent.RejectedExecutionExceptionをスローします
    • ThreadPoolExecutor.CallerRunsPolicy()—現在のタスクの追加を再試行すると、自動的にexecute()メソッドが繰り返し呼び出されます
    • ThreadPoolExecutor.DiscardOldestPolicy()—古いタスクを破棄します
    • ThreadPoolExecutor.DiscardPolicy()—現在のタスクを破棄します
39件の元の記事を公開 賞賛3 訪問数3344

おすすめ

転載: blog.csdn.net/administratorJWT/article/details/105633396