web-dev-qa-db-ja.com

スレッドは自分自身を削除しますか?

Swingアプリケーションに取り組んでいたとしましょう。そのほとんどはmainメソッド内でSwingUtilities.invokeLater()を使用してEDTで実行されます。これは、Swingで行う必要があると聞いた(私が間違っている場合は修正してください)ためです。

ただし、その一部はEDTで実行できません。これらの部分は完了するまでに時間がかかる部分です(これは、EDTでの長いタスクは、EDTが実行する必要があるGUIの処理に干渉するため、これらの種類のタスクは、異なるスレッドで並行して実行する必要があるためです。この仮定は正しいですか?)

これを行うには、完了するまでに時間がかかり、プログラムの他の部分のようにEDTで実行できないタスクを実行する必要がある場合、新しいスレッドを作成して、そのタスクをその内部で実行します。

私の質問は:その新しいスレッドのrun()メソッドが終了すると、別名スレッドはそのジョブを終了しました。自分自身を削除しますか?それともメモリに存在し続けますか?

4
Aviv Cohn

その新しいスレッドのrun()メソッドが終了すると、別名スレッドはそのジョブを終了します。自分自身を削除しますか?それともメモリに存在し続けますか?

主に自分自身を削除します。ネイティブスレッド(OSリソース)は通常1 破棄され、スレッドスタックメモリセグメント(OSリソース)は通常削除されます。スレッドのスレッドローカルマップ、ランナブル、およびThreadオブジェクトの他のいくつかのフィールドはnullになります。

リモートエージェントによって(とりわけ)使用される、JVMによって管理されるいくつかの追加(ユーザー空間)スレッド記述子があります。いつ破壊されるかはわかりませんが、証拠によると、2 スレッドのrun()が終了すると破棄されます。

Threadオブジェクトは、到達可能な限り存在し続けます。したがって、スレッドが終了したときにeverythingを消したい場合は、ThreadまたはRunnableへの参照を保持しないでください。

これはすべて複雑で、JVMバージョンとOS固有の両方です。使用しているJavaのバージョンの正確な答えが本当に必要な場合は、ソースコードを確認してください。


1-理論的には、JVMはネイティブスレッドとスレッドスタックセグメントをリサイクルできます。ただし、アプリケーションでスレッドリサイクルをより高いレベルで実装することは標準的な方法です。例えばExecutorServiceForkJoinPool、またはサードパーティのスレッドプールを使用する。このようなアプリケーションの場合、低レベルのリサイクルは冗長であり、パフォーマンスを低下させる可能性があります。

2-通常、jstack出力に終了スレッドが表示されないという証拠です。ただし、逆に、リモートエージェントがスレッドを監視している場合、スレッド記述子の削除が遅延または防止される可能性があります。

7
Stephen C