2012-03-11 46 views
7

子スレッドが実行を完了する前にメインスレッドが終了しますか?親スレッドが終了した場合子スレッドが実行を完了する前にメインスレッドが終了しますか?

私は2件の記事上記の記事で

http://www.cs.mtu.edu/~shene/NSF-3/e-Book/FUNDAMENTALS/thread-management.html

に読み、「スレッドの終了」パラでは、それはその子スレッドのすべてが同様に終了し、「レッドに述べています。 "上記の記事で

http://www.roseindia.net/java/thread/overview-of-thread.shtml

、そのページの状態で最後の行「main()メソッドの実行が終了することができますが、すべてのスレッドがその実行を完了持つまでプログラムが実行し続けます。」。

私は料金が矛盾しています。私が間違っているなら、専門家は私を訂正してください。

私のプログラムでは、Mainメソッドを持つプログラムが2スレッドのコンストラクタを呼び出します。それぞれのスレッドのコンストラクタで、私はstart()メソッドを持っています。

 TestA A = new TestA("TestA"); 
    TestB B = new TestB("TestB"); 

    public TestA(String name) { 
    System.out.println(name); 
    t = new Thread(this); 
    t.start(); 
} 

子スレッドが実行を完了する前にメインスレッドは何が起こるか知りたいですか?もしそうなら、子スレッドはとにかくスレッドを実行し続けますか?

私はプログラムを実行しようとしましたが、メインスレッドが終了してもすべての子スレッドが実行されることがあります。 2つのスレッドで、私はいくつかのファイルを処理しています。 testAスレッドA単独では、1つのファイルだけが何度か処理されません。しかし何度も、すべてのファイルが処理されており、私は何の問題もありません。

答えて

20

Javaでは、ユーザースレッドとデーモンスレッドと呼ばれる別の種類のスレッドが区別されます。これらの2つのタイプのスレッドの違いは、アプリケーションで実行中のスレッドのみがデーモンスレッド(つまり、ユーザスレッドがない)であるとJVMが判断した場合、Javaランタイムはアプリケーションを終了させるということです。一方、少なくとも1つのユーザースレッドが存続している場合、Javaランタイムはアプリケーションを終了しません。

main()メソッドが最初にJavaランタイムからコントロールを受け取ると、そのメソッドはユーザースレッドのコンテキストで実行されます。 main-methodスレッドまたは他のユーザースレッドが存続している限り、アプリケーションは引き続き実行されます。

あなたの場合、スレッドはユーザースレッドであるため、メインスレッドが終了する前に完了することができます。

私はいくつかのファイルを処理しています。 testAスレッドA単独では、1ファイルだけでも は何度も処理されません。しかし何度も。

上記の理由は、スレッド終了以外のものかもしれません。

は、Java仮想マシンが起動し、通常のmainという名前のメソッドを呼び出す単一 非デーモンスレッドが(通常はそこにある:それは、ファイルロック、同期の問題など

Java Thread API documentationからかもしれません一部 指定クラス)。

Runtimeクラスのexitメソッドが呼び出され、セキュリティーマネージャー が終了操作を実行できるようになったときに、Java仮想マシンは スレッドを実行し続けます。すべてのスレッド がデーモンスレッドではなく、 呼び出しから実行メソッドに戻るか、実行方法を超えて を伝播する例外をスローするかのいずれかによって、終了しました。

+0

詳細な説明をありがとうございます。 「あなたの場合、スレッドはユーザースレッドであり、したがってメインスレッドが終了する前に完了することが許可されています」と言いました。ここでは、メインメソッド()のプログラムではなく、Java実行時間になる「メインスレッド」を意味します。正しい? – user1257836

+0

mainメソッドを持つクラスとmainメソッドの内部で作成されるスレッドはすべてUserスレッドです。これらのスレッドはすべて独立して同時に実行されます。私はSystem.out.println(「メインメソッドの終了」)を与えたので、メインメソッドの最後に。これは子スレッドのsystem.out.println()の前に出力されます。これは、メインスレッド(メインメソッドを持つクラス)が子スレッドの前であっても終了できると思うようになりました。これはきちんとした正しい行動方法ですか? – user1257836

+0

ファイルロックの意味を明確にしてください。前もって感謝します!! – user1257836

2

メインスレッドが終了すると、そのスレッドが子スレッドを取得します。おそらく「仕上げ」によって、第2の記事は単に子供を待つこと以外の操作を意味しない。メインスレッドがSystem.exit(0)を呼び出すと、それは終わった - すべての体が死ぬ。

threadAとthreadBの2つのスレッドが実行されているとします。主な方法で。最初のコードは、スレッドを終了させる良い方法である - 多くの方法のひとつ:

以下
threadA.start(); 
threadB.start(); 
final long intercept = 300; 
long startTime = System.currentTimeMillis(); 
while (threadA.isAlive() && mis.isAlive()) { 
    threadA.join(intercept); 
if (System.currentTimeMillis() - startTime > intercept) { 
    threadB.interrupt(); 
    threadA.interrupt(); 
    threadA.join(); 
} 
} 
System.exit(0); 

メイン内からすべてのスレッドを殺すの突然の方法である:

System.exit(0); 
+0

お返事ありがとうございます。私はプログラムでSystem.exit(0)を使用したことはありません。 "メインスレッドが終了すると、" .amはまだクリアされていません。メインメソッドを持つプログラムは2つのスレッドを作成し、その完了を取得します。しかし、生成された子スレッドは続行されますが、それは正しくありませんか? – user1257836

3

バックグラウンドスレッドがしますMAINスレッドが完了しても実行を継続する。

MAINにMAINを終了させたい場合(MAINが完了したときなど)、MAINにスレッドが時折見える「実行中」フラグ変数(「volatile」と設定する必要があります)を設定します。 MAINはMAINを停止させたいときに、それをfalse(変数)またはnull(オブジェクト)に設定します。 falseまたはnullの場合、スレッドは "return;"する必要があります。

これは実装するには多少複雑ですが、多くの方法がありますが、Runnableをインナークラスにするのが最も簡単です。そのため、Runnableはフラグを簡単に共有できます。

最高の実装では、Javaアプレットの起動/停止ルーチンでこの手法を参照してください。