私はこの声明を読んだ:
メインスレッドは、実行を終了する最後のスレッドでなければなりません。メインスレッドが停止すると、プログラムは終了します。
本当ですか?
「メインスレッドが死んでもプログラムが止まらない」ということも知りました。
私の理解によると、プログラムを開始すると、JVMは1つのスレッドを作成してプログラムを実行します。 JVMは、プログラムを実行するための1つのユーザースレッドを作成します。このスレッドはメインスレッドと呼ばれます。クラスのメインメソッドはメインスレッドから呼び出されます。プログラムがメインスレッドから新しいスレッドを生成した場合、プログラムは最後のスレッドが終了するまで停止します。
どちらが本当ですか?
非デーモンスレッドがすべて終了すると、プログラムは終了します(デーモンスレッドは、setDaemon(true)
でマークされたスレッドです。通常、ユーティリティスレッドに使用されます)。 javadoc から:
Java仮想マシンが起動すると、通常、デーモンではないスレッドが1つあります(通常、指定されたクラスのmainという名前のメソッドを呼び出します)。Java =仮想マシンは、次のいずれかが発生するまでスレッドを実行し続けます。
- クラスRuntimeのexitメソッドが呼び出され、セキュリティマネージャが終了操作の実行を許可しました。
- デーモンスレッドではないすべてのスレッドが、runメソッドへの呼び出しから戻るか、runメソッドを超えて伝播する例外をスローすることによって停止しました。
私はこの声明を読みました。「メインスレッドは実行を終了する最後のスレッドでなければなりません。メインスレッドが停止すると、プログラムは終了します。
いいえそうではありません。 最後の非デーモンスレッドが終了すると、仮想マシンは終了します。メインスレッドである必要はありません。
簡単な例:
public static void main(String[] args) {
System.out.println("Main thread started");
new Thread(new Runnable() {
@Override
public void run() {
System.out.println("Second thread started");
try {
Thread.sleep(2000); // wait two seconds
} catch(Exception e){}
System.out.println("Second thread (almost) finished");
}
}).start();
System.out.println("Main thread (almost) finished");
}
メインスレッドが停止すると、プログラムは終了します。
デーモン以外のスレッド(またはSystem.exitと呼ばれる誰か)が実行されなくなると、プログラムは終了します。メインスレッドはずっと前に終了している可能性があります。
JVMはメインスレッドとすべての非デーモンスレッドの実行が終了すると終了します。
新しいスレッドを作成するときは、Thread.setDaemon(true)
を呼び出してデーモンスレッドにすることができます。これを行うと、JVMはこのスレッドが終了してから実行されるまで待機しません。これは、プログラムが停止するまでバックグラウンドで実行されるスレッドを作成する場合に役立ちます。
新しいスレッドを作成し、Thread.setDaemon(true)
を呼び出さない場合、メインスレッドが終了していても、JVMはこのスレッドが完了するまで終了を遅らせます。
メインスレッドが開始されたとき、スレッドクラスのjoin()を使用してこのスレッドを待機できなくなるまで、作成された別のスレッドを待機しません。したがって、基本的には、子スレッドまたはサブスレッドがタスクの処理により多くの時間を費やし、join()を使用しない場合、メインスレッドが停止する可能性があります。メインスレッドを維持するには、join()を使用して、この関連スレッドのみが停止した後にメインスレッドが停止するようにする必要があります。
このリンクをチェック
http://download.Oracle.com/javase/1.5.0/docs/api/Java/lang/Thread.html#join%28%29
最初のステートメントは正確ではありません。 Javaプログラムは、デーモン以外のすべてのスレッドが終了したとき、またはSystem.exit()
またはRuntime.exit()
が呼び出されたときに終了します。
run()
メソッドを終了すると、スレッドは終了します。 run()
メソッドを明示的に実装せず、代わりにmain()
を実装し、main()
をrun()
から呼び出すため、メインスレッドは特別です。したがって、main()
が終了すると、メインスレッドが終了します。
しかし、メインスレッドは必ずしも最後のスレッドではありません。
これは、JVM仕様の3番目のドラフトからのものであるため、私が認識している最新のものです。
5.7仮想マシンの終了
Java仮想マシンは、次のいずれかの場合にすべてのアクティビティを終了し、終了します。•デーモンスレッドではないすべてのスレッドが終了します。 •一部のスレッドがクラスRuntimeまたはクラスSystemの終了メソッドを呼び出し、セキュリティマネージャーによって終了操作が許可されています。
メインスレッドは区別されないので、メインスレッドのみが適用されるとは限りません。