shutdown() メソッド
スレッド プールを使用する場合、shutdown() メソッドを呼び出した後、スレッド プールは新しい実行タスクを受け入れなくなります。ただし、shutdown() メソッドを呼び出す前にタスク キューに配置されたタスクは、引き続き実行する必要があります。このメソッドはノンブロッキング メソッドであり、呼び出されるとすぐに戻り、タスク キュー内のすべてのタスクが実行されるのを待ってから戻ります。以下に示すように、shutdown() メソッドのソース コードを見てみましょう。
public void shutdown() { //获取线程池的全局锁 final ReentrantLock mainLock = this.mainLock; mainLock.lock(); try { //检查是否有关闭线程池的权限 checkShutdownAccess(); //将当前线程池的状态设置为SHUTDOWN advanceRunState(SHUTDOWN); //中断Worker线程 interruptIdleWorkers(); //为ScheduledThreadPoolExecutor调用钩子函数 onShutdown(); // hook for } finally { //释放线程池的全局锁 mainLock.unlock(); } //尝试将状态变为TERMINATED tryTerminate(); }
一般に、shutdown() メソッドのコードは比較的単純で、最初にスレッド プールを閉じる権限があるかどうかを確認し、権限がある場合は、中断する権限があるかどうかを再度確認します。権限がない場合は SecurityException がスローされ、コードは次のようになります。
//检查是否有关闭线程池的权限 checkShutdownAccess(); //将当前线程池的状态设置为SHUTDOWN advanceRunState(SHUTDOWN); //中断Worker线程 interruptIdleWorkers();
このうち、checkShutdownAccess()メソッドの実装コードは以下のとおりです。
private void checkShutdownAccess() { SecurityManager security = System.getSecurityManager(); if (security != null) { security.checkPermission(shutdownPerm); final ReentrantLock mainLock = this.mainLock; mainLock.lock(); try { for (Worker w : workers) security.checkAccess(w.thread); } finally { mainLock.unlock(); } } }
checkShutdownAccess() メソッドのコードを理解するのは比較的簡単です。このメソッドは、スレッド プールのグローバル ロックが使用されている間、スレッド プールを閉じる権限があるかどうかを検出します。
次に、次に示すように、advancedRunState(int) メソッドのソース コードを確認します。
private void advanceRunState(int targetState) { for (;;) { int c = ctl.get(); if (runStateAtLeast(c, targetState) || ctl.compareAndSet(c, ctlOf(targetState, workerCountOf(c)))) break; } }
advanceRunState(int) メソッドの全体的なロジックは、現在のスレッド プールの状態が指定された状態であるかどうかを判断することです。shutdown() メソッドで渡される状態は SHUTDOWN です。SHUTDOWN の場合は、直接返される; if SHUTDOWN でない場合は、現在のスレッド プールのステータスを SHUTDOWN に設定します。
次に、以下に示すように、showdown() メソッドによって呼び出されるinterruptIdleWorkers() メソッドを見てみましょう。
private void interruptIdleWorkers() { interruptIdleWorkers(false); }
interruptIdleWorkers() メソッドがinterruptIdleWorkers(boolean) メソッドを呼び出していることがわかります。次に示すように、interruptIdleWorkers(boolean) メソッドのソース コードを続けて見てください。
private void interruptIdleWorkers(boolean onlyOne) { final ReentrantLock mainLock = this.mainLock; mainLock.lock(); try { for (Worker w : workers) { Thread t = w.thread; if (!t.isInterrupted() && w.tryLock()) { try { t.interrupt(); } catch (SecurityException ignore) { } finally { w.unlock(); } } if (onlyOne) break; } } finally { mainLock.unlock(); } }
上記のコードの全体的なロジックは次のとおりです。スレッド プールのグローバル ロックを取得し、すべてのワーカー スレッドを循環し、スレッドが中断されているかどうかを検出し、中断されていない場合はワーカー スレッドがロックを取得します。スレッドの割り込みメソッドを実行し、スレッドが取得したロックを解放します。このとき、onlyOne パラメータが true の場合、ループを終了します。それ以外の場合は、すべてのワーカー スレッドをループして同じ操作を実行します。最後に、スレッド プールのグローバル ロックが解放されます。
次に、shutdownNow() メソッドを見てみましょう。
shutdownNow() メソッド
スレッド プールの shutdownNow() メソッドが呼び出されると、スレッド プールは新しい実行タスクを受け入れなくなり、タスク キューに存在するタスクも破棄されます。実行中のワーカー スレッドもすぐに中断されます。同時に、メソッドはすぐに戻ります。このメソッドの戻り値は、現在のタスク キュー内の破棄されたタスクのリストです。
shutdownNow() メソッドのソース コードは次のとおりです。
public List<Runnable> shutdownNow() { List<Runnable> tasks; final ReentrantLock mainLock = this.mainLock; mainLock.lock(); try { //检查是否有关闭权限 checkShutdownAccess(); //设置线程池的状态为STOP advanceRunState(STOP); //中断所有的Worker线程 interruptWorkers(); //将任务队列中的任务移动到tasks集合中 tasks = drainQueue(); } finally { mainLock.unlock(); } /尝试将状态变为TERMINATED tryTerminate(); //返回tasks集合 return tasks; }
shutdownNow() メソッドのソース コードの全体的なロジックは、shutdown() メソッドと基本的に同じですが、shutdownNow() メソッドがスレッド プールのステータスを STOP に設定し、すべてのスレッド プールを中断する点が異なります。ワーカー スレッドを作成し、タスク キューに入れます。すべてのタスクがタスク コレクションに移動され、返されます。
shutdownNow() メソッドがすべてのスレッドに割り込むと、interruptWorkers() メソッドが呼び出されることがわかります。次に、以下に示すinterruptWorkers() メソッドのソース コードを見てみましょう。
private void interruptWorkers() { final ReentrantLock mainLock = this.mainLock; mainLock.lock(); try { for (Worker w : workers) w.interruptIfStarted(); } finally { mainLock.unlock(); } }
interruptWorkers() メソッドのロジックは比較的単純です。スレッド プールのグローバル ロックを取得し、すべてのワーカー スレッドを循環し、スレッドを順番に割り込み、最後にグローバル ロックを解放します。スレッドプール。
スレッドを中断するために、interruptWorkers() メソッド内で、Worker クラスのinterruptIfStarted() メソッドが実際に呼び出されます。以下に示すように、Worker クラスのinterruptIfStarted() メソッドのソース コードを見てみましょう。 。
void interruptIfStarted() { Thread t; if (getState() >= 0 && (t = thread) != null && !t.isInterrupted()) { try { t.interrupt(); } catch (SecurityException ignore) { } } }
本質的には、スレッドを中断するために Thread クラスの中断() メソッドを呼び出していることがわかりました。
awaitTermination(long, TimeUnit) メソッド
スレッド プールが awaitTermination(long, TimeUnit) メソッドを呼び出すと、スレッド プールのステータスが TERMINATED に変更されるまで、呼び出し元のスレッドはブロックされます。 . リターンするか、タイムアウト期間に達するとリターンします。次に、以下に示す awaitTermination(long, TimeUnit) メソッドのソース コードを見てみましょう。
public boolean awaitTermination(long timeout, TimeUnit unit) throws InterruptedException { //获取距离超时时间剩余的时长 long nanos = unit.toNanos(timeout); //获取Worker线程的的全局锁 final ReentrantLock mainLock = this.mainLock; //加锁 mainLock.lock(); try { for (;;) { //当前线程池状态为TERMINATED状态,会返回true if (runStateAtLeast(ctl.get(), TERMINATED)) return true; //达到超时时间,已超时,则返回false if (nanos <= 0) return false; //重置距离超时时间的剩余时长 nanos = termination.awaitNanos(nanos); } } finally { //释放锁 mainLock.unlock(); } }
上記のコードの全体的なロジックは次のとおりです: まずワーカー スレッドの排他ロックを取得し、次にループして現在のスレッド プールが既に TERMINATED 状態かどうかを確認します。そうであれば、直接 true を返します。それ以外の場合は、タイムアウトしたかどうかを確認し、タイムアウトした場合は false を返します。タイムアウトしない場合は、タイムアウトまでの残り時間をリセットしてください。次に、次のサイクルに入り、現在のスレッド プールが TERMINATED 状態かどうかを再度確認します。そうであれば、直接 true を返します。それ以外の場合は、タイムアウトしたかどうかを確認し、タイムアウトした場合は、false を返します。タイムアウトしない場合は、タイムアウトまでの残り時間をリセットしてください。このループは、スレッド プールのステータスが TERMINATED になるかタイムアウトになるまで継続します。
以上がJava スレッド プールを正常にシャットダウンするにはどうすればよいですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

javaispopularforsoss-platformdesktopapplicationsduetoits "writeonce、runaynay" philosophy.1)itusesbytecodatiTatrunnanyjvm-adipplatform.2)ライブラリリケンディンガンドジャヴァフククレアティック - ルルクリス

Javaでプラットフォーム固有のコードを作成する理由には、特定のオペレーティングシステム機能へのアクセス、特定のハードウェアとの対話、パフォーマンスの最適化が含まれます。 1)JNAまたはJNIを使用して、Windowsレジストリにアクセスします。 2)JNIを介してLinux固有のハードウェアドライバーと対話します。 3)金属を使用して、JNIを介してMacOSのゲームパフォーマンスを最適化します。それにもかかわらず、プラットフォーム固有のコードを書くことは、コードの移植性に影響を与え、複雑さを高め、パフォーマンスのオーバーヘッドとセキュリティのリスクをもたらす可能性があります。

Javaは、クラウドネイティブアプリケーション、マルチプラットフォームの展開、および言語間の相互運用性を通じて、プラットフォームの独立性をさらに強化します。 1)クラウドネイティブアプリケーションは、GraalvmとQuarkusを使用してスタートアップ速度を向上させます。 2)Javaは、埋め込みデバイス、モバイルデバイス、量子コンピューターに拡張されます。 3)Graalvmを通じて、JavaはPythonやJavaScriptなどの言語とシームレスに統合して、言語間の相互運用性を高めます。

Javaの強力なタイプ化されたシステムは、タイプの安全性、統一タイプの変換、多型を通じてプラットフォームの独立性を保証します。 1)タイプの安全性は、コンパイル時間でタイプチェックを実行して、ランタイムエラーを回避します。 2)統一された型変換ルールは、すべてのプラットフォームで一貫しています。 3)多型とインターフェイスメカニズムにより、コードはさまざまなプラットフォームで一貫して動作します。

JNIはJavaのプラットフォームの独立を破壊します。 1)JNIは特定のプラットフォームにローカルライブラリを必要とします。2)ローカルコードをターゲットプラットフォームにコンパイルおよびリンクする必要があります。3)異なるバージョンのオペレーティングシステムまたはJVMは、異なるローカルライブラリバージョンを必要とする場合があります。

新しいテクノロジーは、両方の脅威をもたらし、Javaのプラットフォームの独立性を高めます。 1)Dockerなどのクラウドコンピューティングとコンテナ化テクノロジーは、Javaのプラットフォームの独立性を強化しますが、さまざまなクラウド環境に適応するために最適化する必要があります。 2)WebAssemblyは、Graalvmを介してJavaコードをコンパイルし、プラットフォームの独立性を拡張しますが、パフォーマンスのために他の言語と競合する必要があります。

JVMの実装が異なると、プラットフォームの独立性が得られますが、パフォーマンスはわずかに異なります。 1。OracleHotspotとOpenJDKJVMは、プラットフォームの独立性で同様に機能しますが、OpenJDKは追加の構成が必要になる場合があります。 2。IBMJ9JVMは、特定のオペレーティングシステムで最適化を実行します。 3. Graalvmは複数の言語をサポートし、追加の構成が必要です。 4。AzulzingJVMには、特定のプラットフォーム調整が必要です。

プラットフォームの独立性により、開発コストが削減され、複数のオペレーティングシステムで同じコードセットを実行することで開発時間を短縮します。具体的には、次のように表示されます。1。開発時間を短縮すると、1セットのコードのみが必要です。 2。メンテナンスコストを削減し、テストプロセスを統合します。 3.展開プロセスを簡素化するための迅速な反復とチームコラボレーション。


ホットAIツール

Undresser.AI Undress
リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover
写真から衣服を削除するオンライン AI ツール。

Undress AI Tool
脱衣画像を無料で

Clothoff.io
AI衣類リムーバー

Video Face Swap
完全無料の AI 顔交換ツールを使用して、あらゆるビデオの顔を簡単に交換できます。

人気の記事

ホットツール

WebStorm Mac版
便利なJavaScript開発ツール

DVWA
Damn Vulnerable Web App (DVWA) は、非常に脆弱な PHP/MySQL Web アプリケーションです。その主な目的は、セキュリティ専門家が法的環境でスキルとツールをテストするのに役立ち、Web 開発者が Web アプリケーションを保護するプロセスをより深く理解できるようにし、教師/生徒が教室環境で Web アプリケーションを教え/学習できるようにすることです。安全。 DVWA の目標は、シンプルでわかりやすいインターフェイスを通じて、さまざまな難易度で最も一般的な Web 脆弱性のいくつかを実践することです。このソフトウェアは、

SublimeText3 英語版
推奨: Win バージョン、コードプロンプトをサポート!

EditPlus 中国語クラック版
サイズが小さく、構文の強調表示、コード プロンプト機能はサポートされていません

メモ帳++7.3.1
使いやすく無料のコードエディター

ホットトピック









