処理能力と同時実行性を向上させるために、Web コンテナは通常、リクエストを処理するタスクをスレッド プールに配置します。JDK のネイティブ スレッド プールは、CPU を集中的に使用するタスクに本質的に適しているため、Tomcat はこれを変更しました。 Tomcat スレッドプールの原則実際、ThreadPoolExecutor のパラメータには主に次の重要なポイントがあります。 スレッド数を制限する キューの長さを制限する Tomcat はこれら 2 つのリソースを制限する必要があります。そうしないと、同時実行性が高い場合に CPU とメモリが枯渇する可能性があります。 // カスタマイズされたタスク キュー taskqueue = new TaskQueue(maxQueueSize); // カスタマイズされたスレッドファクトリー TaskThreadFactory tf = new TaskThreadFactory(namePrefix, デーモン、 スレッド優先度を取得します。 ); // カスタム スレッド プール executor = new ThreadPoolExecutor(getMinSpareThreads(), getMaxThreads()、 最大アイドル時間、 時間単位.ミリ秒、 タスクキュー、 tf); Tomcat にはスレッド数制限もあり、次のように設定します。
Tomcat スレッド プールには独自の特別なタスク処理フローもあり、execute メソッドを書き換えることで独自の特別なタスク処理ロジックを実装します。
Tomcat と JDK スレッド プールの違いは、ステップ 3 にあります。スレッドの総数が最大数に達すると、Tomcat はすぐに拒否戦略を実行せず、タスク キューにタスクを追加しようとします。追加が失敗すると、拒否戦略が再度実行されます。 具体的にはどのように実現されるのでしょうか? public void execute(実行可能なコマンド、長いタイムアウト、TimeUnit 単位) { 送信されたCountを増加して取得します。 試す { //タスクを実行するには、JDK ネイティブ スレッド プールの execute 関数を呼び出します。super.execute(command); } キャッチ (RejectedExecutionException rx) { // スレッドの総数がmaximumPoolSizeに達すると、JDKネイティブスレッドプールはデフォルトの拒否ポリシーを実行します。if (super.getQueue() instanceof TaskQueue) { 最終的な TaskQueue キュー = (TaskQueue)super.getQueue(); 試す { // タスクをタスクキューに追加し続ける if (!queue.force(command, timeout, unit)) { 送信されたCountを減分して取得します。 // バッファ キューがまだいっぱいの場合、挿入は失敗し、拒否戦略が実行されます。 新しい RejectedExecutionException("...") をスローします。 } } } } } タスクキューのカスタマイズTomcat スレッド プールの execute メソッドの最初の行: 送信されたCountを増加して取得します。 タスクが失敗して例外がスローされると、カウンターは 1 つ減ります。 送信されたCountを減分して取得します。 Tomcat スレッド プールは、 submittedCount変数を使用して、スレッド プールに送信されたが実行されていないタスクの数を維持します。
Tomcat のタスク キュー TaskQueue は、JDK の LinkedBlockingQueue を拡張します。Tomcat はこれに容量を与え、それを親クラス LinkedBlockingQueue のコンストラクターに渡します。 パブリッククラスTaskQueueはLinkedBlockingQueue<Runnable>を拡張します。 パブリックタスクキュー(int 容量) { スーパー(容量); } ... } 容量パラメータは Tomcat の maxQueueSize パラメータによって設定されますが、maxQueueSize のデフォルト値はInteger.MAX_VALUE です。現在のスレッド数がコア スレッド数に達した後、別のタスクがある場合、スレッド プールはタスクをタスク キューに追加し、常に成功するので、新しいスレッドを作成する機会はありません。 この問題を解決するために、TaskQueue は LinkedBlockingQueue#offer を書き換え、適切なタイミングでタスクの追加が失敗したことを示す false を返します。このとき、スレッド プールは新しいスレッドを作成します。
パブリッククラスTaskQueueはLinkedBlockingQueue<Runnable>を拡張します。 ... @オーバーライド // スレッドプールがタスクキューメソッドを呼び出すと、現在のスレッド数 > コアスレッド数 public boolean offer(Runnable o) { // スレッド数が最大に達した場合、新しいスレッドは作成できず、(parent.getPoolSize() == parent.getMaximumPoolSize()) の場合にのみタスク キューに追加できます。 super.offer(o) を返します。 // これまでのところ、最大スレッド数 > 現在のスレッド数 > コアスレッド数であることを示しています // 新しいスレッドを作成できることを示しています: // 1. 送信されたタスクの数 < 現在のスレッド数の場合 // アイドル状態のスレッドがまだ存在し、新しいスレッドを作成する必要がないことを意味します if (parent.getSubmittedCount()<=(parent.getPoolSize())) super.offer(o) を返します。 // 2. 送信されたタスクの数 > 現在のスレッド数の場合 // スレッドが足りない場合は、false を返して新しいスレッドを作成します if (parent.getPoolSize()<parent.getMaximumPoolSize()) false を返します。 // デフォルトでは、タスクは常にタスクキューに入れられます。 return super.offer(o); } } したがって、Tomcat は、タスク キューの長さが無限の場合にスレッド プールが新しいスレッドを作成できるように、送信されたタスクの数を維持します。 Tomcat が JDK ネイティブ スレッド プールのバグを修正する方法について説明したこの記事はこれで終わりです。Tomcat JDK ネイティブ スレッド プールの詳細については、123WORDPRESS.COM の以前の記事を検索するか、以下の関連記事を引き続き参照してください。今後とも 123WORDPRESS.COM をよろしくお願いいたします。 以下もご興味があるかもしれません:
|
Python 3.4でMySQLデータベースを使用する詳細なプロセスは次のとおりです。 Window...
エラー 1290 (HY000) : MySQL サーバーは –secure-file-priv オ...
序文Tomcat は、無数のチューニング オプションを備えた、広く使用されている Java Web ...
まず第一に、この効果は古い話題であるはずだということはわかっています。今日ファイルを整理していたら、...
導入Vue Router 、 Vue.jsの公式ルーティング マネージャーです。 Vue.jsのコア...
(I)ウェブページのカラーマッチングの基本概念(1)白黒の言葉は永遠のテーマです。誰もそれを悪く言う...
目次方法1: set: データ型ではなくデータ構造であり、メンバーは一意である方法2: オブジェクト...
以下のように表示されます。 test コマンドはファイルが存在するかどうかを判断します。 ssh u...
適切に機能するテーブル プロパティ設定:コードをコピーコードは次のとおりです。 <テーブル セ...
序文現在の JavaScript には列挙の概念がありません。一部のシナリオでは、列挙を使用するとデ...
1. 環境整備1.MySQLインストールパス: /usr/local 2. CentOS 6.2 ...
目次1. はじめに2. 設定手順1. はじめに1. NAT モード (VMnet8) は、仮想マシン...
導入前回の記事では、Redis をインストールして設定しましたが、まだ終わりではありません。PHP ...
目次序文1. MySQLはSSL構成を有効にする1.1 SSLが有効になっているかどうかを確認する1...
コンポーネントが詳細になるにつれて、複数のコンポーネントが状態を共有する状況に遭遇するでしょう。Vu...