33

私は自分自身にJavaスレッドを教えていましたが、少し混乱する何かに気づきました。engine実装というクラスを作りましたRunnable。runメソッドは、「Hello World」を出力し、1秒間スリープして、繰り返します。

私の主な方法では、次のようになります。

public static void main(String[] args) {
    Thread thread = new Thread(engine);
    thread.start();
    System.out.println("Done.");
}

予想通り、「HelloWorld」と「Done」が表示されます。すぐに印刷されたため、mainメソッドが終了しましたが、予期していなかったのは、mainの終了に達した後も、開始したスレッドが実行を継続したことです。

メインが終了した後もプログラムが実行され続けるのはなぜですか?mainが終了すると、プロセスが終了し、すべてのスレッドが強制的にクリーンアップされると思いました。これは、Javaプログラムを終了するために、すべてのスレッドを明示的に結合/強制終了する必要があることを意味しますか?

4

6 に答える 6

30

それがその仕組みだからです。プログラムは、System.exit()が呼び出されたとき、または最後の非デーモンスレッドの実行が停止したときに終了します。

そしてそれは理にかなっています。このルールがないと、たとえば、GUIを生成するだけで構成されるすべてのJavaプログラムは、プログラムがすぐに終了しないように、無限にwait()する必要があります。

于 2012-12-16T19:32:22.000 に答える
28

mainメソッドが終了したときにプログラムを終了させたい場合は、スレッドデーモンを作成することを検討してください。ただし、mainが終了すると、デーモンスレッドが中止されることに注意してください。
次のようにデーモンtheadを作成できます。

Thread t = new Thread(...);
t.setDaemon(true);

デーモン以外のスレッドはすべてユーザースレッドです。これらのスレッドは、jvmのクローズを停止しています。

于 2012-12-16T19:32:15.667 に答える
12

ユーザースレッドは、親スレッド、つまり作成者スレッドの存続期間に関係なく実行され続けます。Thread.joinしたがって、スレッドが終了する前に呼び出すことによって、スレッドを明示的に結合する必要がありmainます。

JavadocからThread

Java仮想マシンが起動すると、通常、デーモン以外のスレッドが1つ存在します(通常、指定されたクラスのmainという名前のメソッドを呼び出します)。Java仮想マシンは、次のいずれかが発生するまでスレッドを実行し続けます。

  1. クラスRuntimeのexitメソッドが呼び出され、セキュリティマネージャがexit操作の実行を許可しました。

  2. runメソッドの呼び出しから戻るか、runメソッドを超えて伝播する例外をスローすることにより、デーモンスレッドではないすべてのスレッドが停止しました。

tスレッドが実行されている場合でもJVMを終了させたい場合は、スレッドtをデーモンスレッドにする必要があります。

t.setDaemon(true);
于 2012-12-16T19:28:48.150 に答える
11

スレッドには、ユーザーとデーモンの 2 種類があります。ユーザースレッドがなくなると、プロセスは終了します。メイン スレッドは常にユーザー スレッドです。開始するスレッドはユーザー スレッドでもあるため、プロセスが実行されている間はプロセスが存続します。

開始する前にスレッドを呼び出すと、関数が戻るsetDaemon(true)とすぐにプロセスが (多かれ少なかれ) 終了します。main()

于 2012-12-16T19:35:03.790 に答える
7

Java 言語仕様のセクション 12.8 には、次のように記載されています。

12.8. プログラム終了

次の 2 つのいずれかが発生すると、プログラムはすべてのアクティビティを終了し、終了します。

デーモン スレッドではないすべてのスレッドが終了します。

一部のスレッドはクラス Runtime またはクラス System の exit メソッドを呼び出しますが、セキュリティ マネージャーによって終了操作が禁止されていません。

これは、メイン スレッドが終了するのに十分ではないことを意味します。

メインスレッドが終了したときに終了させたい場合は、Thread#setDaemonを使用して新しいスレッドをデーモンにするか、最初に提案したようにThread#joinを使用する必要があります。

于 2012-12-16T19:37:04.430 に答える
0

メインスレッドは作成中のユーザースレッドでもあり、そのライフサイクルは他のユーザースレッドと同様です。
他のユーザー スレッドは、スレッドをデーモン スレッドとして設定しない限り、何らかの理由でメイン スレッドに依存しません。メイン スレッドが作業を完了すると、終了します (他のユーザー スレッドが終了することも、他のユーザー スレッドが実行されているため、プロセスが終了することもありません)。

于 2016-03-22T07:08:19.707 に答える