誰が私のデーモンスレッドがJavaにあるのか教えてもらえますか?
デーモンスレッドは、プログラムが終了してもスレッドがまだ実行されているときにJVMが終了するのを妨げないスレッドです。デーモンスレッドの例はガベージコレクションです。
スレッドが開始する前にsetDaemon(boolean)
メソッドを使用してThread
デーモンのプロパティを変更できます。
もう少しポイント(参照: 実際のJava並行処理 )
デーモン以外のスレッドがすべて終了すると、JVMは停止し、残りのデーモンスレッドは破棄されます:
このため、デーモンスレッドは控えめに使用する必要があり、あらゆる種類のI/Oを実行する可能性のあるタスクに使用するのは危険です。
上記の答えはすべて良いです。違いを説明するために、これは簡単な小さなコードスニペットです。 setDaemon
のtrueとfalseのそれぞれの値で試してみてください。
public class DaemonTest {
public static void main(String[] args) {
new WorkerThread().start();
try {
Thread.sleep(7500);
} catch (InterruptedException e) {
// handle here exception
}
System.out.println("Main Thread ending") ;
}
}
class WorkerThread extends Thread {
public WorkerThread() {
// When false, (i.e. when it's a user thread),
// the Worker thread continues to run.
// When true, (i.e. when it's a daemon thread),
// the Worker thread terminates when the main
// thread terminates.
setDaemon(true);
}
public void run() {
int count = 0;
while (true) {
System.out.println("Hello from Worker "+count++);
try {
sleep(5000);
} catch (InterruptedException e) {
// handle exception here
}
}
}
}
伝統的に、UNIXのデーモンプロセスは、Windowsのサービスのように、常にバックグラウンドで実行されていたものでした。
Javaのデーモンスレッドは、JVMの終了を妨げないものです。具体的には、JVMはデーモンスレッドだけが残ると終了します。 Thread
でsetDaemon()
メソッドを呼び出すことによってそれを作成します。
デーモンスレッドは、デーモンスレッドと同じプロセスで実行されている他のスレッドまたはオブジェクトのサービスプロバイダのようなものです。デーモンスレッドはバックグラウンドサポートタスクに使用され、通常のスレッドの実行中にのみ必要です。通常のスレッドが実行されておらず、残りのスレッドがデーモンスレッドである場合、インタプリタは終了します。
たとえば、HotJavaブラウザは、「Image Fetcher」という名前の最大4つのデーモンスレッドを使用して、ファイルシステムまたはネットワークから必要なスレッドのイメージを取得します。
デーモンスレッドは通常、アプリケーションやアプレットのサービス(「fiddleyビット」のロードなど)を実行するために使用されます。ユーザースレッドとデーモンスレッドの主な違いは、すべてのユーザースレッドが終了したときにのみJVMがプログラムをシャットダウンすることです。実行のメインスレッドを含め、実行中のユーザースレッドがなくなると、デーモンスレッドはJVMによって終了されます。
setDaemon(true/false)? このメソッドは、スレッドがデーモンスレッドであることを指定するために使用されます。
public boolean isDaemon()? このメソッドは、スレッドがデーモンスレッドかどうかを判断するために使用されます。
例えば:
public class DaemonThread extends Thread {
public void run() {
System.out.println("Entering run method");
try {
System.out.println("In run Method: currentThread() is" + Thread.currentThread());
while (true) {
try {
Thread.sleep(500);
} catch (InterruptedException x) {}
System.out.println("In run method: woke up again");
}
} finally {
System.out.println("Leaving run Method");
}
}
public static void main(String[] args) {
System.out.println("Entering main Method");
DaemonThread t = new DaemonThread();
t.setDaemon(true);
t.start();
try {
Thread.sleep(3000);
} catch (InterruptedException x) {}
System.out.println("Leaving main method");
}
}
出力:
C:\Java\thread>javac DaemonThread.Java
C:\Java\thread>Java DaemonThread
Entering main Method
Entering run method
In run Method: currentThread() isThread[Thread-0,5,main]
In run method: woke up again
In run method: woke up again
In run method: woke up again
In run method: woke up again
In run method: woke up again
In run method: woke up again
Leaving main method
C:\j2se6\thread>
デーモンスレッド は、要求の処理やアプリケーション内に存在する可能性があるさまざまなchronjobのように、バックグラウンドでいくつかのタスクを実行すると見なされるスレッドです。
あなたのプログラムが デーモンスレッドしか持っていない場合 残りは終了します。これは通常、これらのスレッドが通常のスレッドと連携してイベントのバックグラウンド処理を提供するためです。
Thread
メソッドを使用してsetDaemon
を daemon oneに指定することができます。これらは通常終了せず、中断もしません。アプリケーションが停止すると停止します。
印刷スプーリングやファイル転送などのサービスに対する要求を処理するバックグラウンドプロセスで、不要な場合は休止します。
- 情報源: オックスフォード辞書による英語
私が明確にしたいと思う1つの誤解:
デーモンスレッドとユーザースレッド通常、プログラマによって作成されたすべてのスレッドはユーザースレッドです(デーモンとして指定するか、親スレッドがデーモンスレッドである場合を除く)。ユーザースレッドは通常、私たちのプログラムコードを実行するためのものです。すべてのユーザースレッドが終了しない限り、JVMは終了しません。
Javaには daemon threadという特別な種類のスレッドがあります。
デーモンスレッドは何に使用されますか?
通常、通常のスレッドのサービスプロバイダとして使用されます。通常、サービス要求を待つか、スレッドのタスクを実行する無限ループがあります。彼らは重要な仕事をすることができません。 (いつCPU時間があるのかわからないので、他にスレッドが実行されていなければいつでも終了できる)
この種のスレッドの典型的な例は、 Javaガベージコレクタ です。
もっとあります...
setDaemon()
メソッドを呼び出す前にstart()
メソッドを呼び出すだけです。スレッドが実行されると、そのデーモンのステータスを変更することはできません。isDaemon()
メソッドを使用します。デーモンスレッドはアシスタントのようなものです。非デーモンスレッドはフロントパフォーマーのようなものです。アシスタントは、パフォーマーが仕事を完成するのを助けます。仕事が完了したら、もう実行するためにパフォーマーによる助けは必要ありません。何の手助けも必要ないので、助手はその場を去ります。そのため、非デーモンスレッドのジョブが終了すると、デーモンスレッドは行進します。
デーモンスレッドは通常のスレッドとまったく同じですが、他の非デーモンスレッドが存在しない場合にのみJVMがシャットダウンする点が異なります。デーモンスレッドは通常、アプリケーションのサービスを実行するために使用されます。
Javaのデーモンスレッドはバックグラウンドで実行され、ガベージコレクションやその他のハウスキーピングタスクのようなバックグラウンドタスクを実行するためにJVMによって主に作成されたスレッドです。
注意事項:
スレッドはそれを作成するスレッド、すなわち親スレッドからそのデーモンの性質を継承し、メインスレッドは非デーモンスレッドであるため、それから作成される他のスレッドはそのため、Javaでmainメソッドを実行するメインスレッドによって作成されたスレッドはデフォルトで非デーモンです。 setDaemon(true)を呼び出して明示的にデーモンを作成するまで、非デーモンのままにします。
Thread.setDaemon(true)はThreadデーモンを作成しますが、JavaでThreadを起動する前にのみ呼び出すことができます。対応するThreadが既に起動されて実行されている場合、IllegalThreadStateExceptionがスローされます。
Javaにおけるデーモンと非デーモンスレッドの違い:
1)JVMはデーモンスレッドが存在する前に終了するのを待ちません。
2)JVMの終了時にデーモンスレッドはユーザースレッドとは異なる方法で処理され、最後にブロックは呼び出されず、スタックは解放されず、JVMは終了します。
デーモンスレッドは一般に「サービスプロバイダ」スレッドとして知られています。これらのスレッドは、プログラムコードではなくシステムコードの実行に使用するべきではありません。これらのスレッドはコードと並行して実行されますが、JVMはいつでもそれらを強制終了できます。 JVMがユーザースレッドを見つけられなくなると、JVMはそれを停止し、すべてのデーモンスレッドは即座に終了します。以下を使用して、非デーモンスレッドをデーモンに設定できます。
setDaemon(true)
Javaでは、 デーモンスレッド はJava仮想マシン(JVM)の終了を妨げないスレッドのタイプの1つです。デーモンスレッドの主な目的は、特に定期的な定期的なタスクや作業の場合にバックグラウンドタスクを実行することです。 JVMが終了すると、デーモンスレッドも停止します。
thread.setDaemon(true)
を設定することによって、スレッドはデーモンスレッドになります。ただし、この値はスレッドの開始前にしか設定できません。
デーモンスレッドはリソースの管理を担当するデーモンプロセスのようなもので、デーモンスレッドはユーザースレッドを提供するためにJava VMによって作成されます。 unix用のアップデートシステムの例、unixはデーモンプロセスです。デーモンスレッドの子は常にデーモンスレッドであるため、デフォルトではdaemonはfalseです。 "isDaemon()"メソッドを使用することで、デーモンまたはユーザーとしてスレッドを確認できます。そのため、デーモンスレッドまたはデーモンプロセスが基本的にリソースの管理を担当します。たとえば、jvmを起動すると、優先度が1、つまりメモリスレッドを管理しているデーモンスレッドであるガベージコレクタが実行されます。ユーザースレッドが生きている限り、jvmは生きています。デーモンthread.jvmはデーモンスレッドを殺すことができません。
デーモンスレッドは誰もが説明したように、JVMの終了を制限するものではないので、基本的には、出口の観点から見てアプリケーションにとっては幸せなスレッドです。
データをサードパーティのサーバーやJMSにプッシュするようなAPIを提供しているときにデーモンスレッドを使用できる場合は、クライアントのJVMレベルでデータを集計してから別のスレッドでJMSに送信する必要があります。これがサーバーにプッシュされる必須データではない場合は、このスレッドをデーモンスレッドにすることができます。この種のデータは、ログプッシュ/集計のようなものです。
よろしく、マニッシュ
デーモンスレッドは、プロセスの他の非デーモンスレッドがまだ実行されている限り、バックグラウンドで実行されるスレッドです。したがって、デーモン以外のスレッドがすべて完了すると、デーモンスレッドは終了します。非デーモンスレッドの例は、Mainを実行しているスレッドです。スレッドは、スレッドが開始される前にsetDaemon()
メソッドを呼び出すことによってデーモンになります。
参考資料: Javaのデーモンスレッド /
私にとっては、デーモンスレッドはユーザースレッドのハウスキーパーのようなものです。すべてのユーザースレッドが終了した場合、デーモンスレッドはジョブを持たず、JVMによって強制終了されます。 YouTubeビデオ で説明しました。
実用的な例を使ってコードだけで話しましょう。私は上のrussの答えが好きですが、私が持っていたどんな疑いも取り除くために、私はそれを少し高めました。ワーカースレッドをdeamon trueに設定して(deamon thread)、もう1回falseに設定して(ユーザースレッド)、2回実行しました。メインスレッドが終了すると、デーモンスレッドが終了することを確認します。
public class DeamonThreadTest {
public static void main(String[] args) {
new WorkerThread(false).start(); //set it to true and false and run twice.
try {
Thread.sleep(7500);
} catch (InterruptedException e) {
// handle here exception
}
System.out.println("Main Thread ending");
}
}
class WorkerThread extends Thread {
boolean isDeamon;
public WorkerThread(boolean isDeamon) {
// When false, (i.e. when it's a user thread),
// the Worker thread continues to run.
// When true, (i.e. when it's a daemon thread),
// the Worker thread terminates when the main
// thread terminates.
this.isDeamon = isDeamon;
setDaemon(isDeamon);
}
public void run() {
System.out.println("I am a " + (isDeamon ? "Deamon Thread" : "User Thread (none-deamon)"));
int counter = 0;
while (counter < 10) {
counter++;
System.out.println("\tworking from Worker thread " + counter++);
try {
sleep(5000);
} catch (InterruptedException e) {
// handle exception here
}
}
System.out.println("\tWorker thread ends. ");
}
}
result when setDeamon(true)
=====================================
I am a Deamon Thread
working from Worker thread 0
working from Worker thread 1
Main Thread ending
Process finished with exit code 0
result when setDeamon(false)
=====================================
I am a User Thread (none-deamon)
working from Worker thread 0
working from Worker thread 1
Main Thread ending
working from Worker thread 2
working from Worker thread 3
working from Worker thread 4
working from Worker thread 5
working from Worker thread 6
working from Worker thread 7
working from Worker thread 8
working from Worker thread 9
Worker thread ends.
Process finished with exit code 0
JVMは、最後の非デーモンスレッドの実行が完了したときに作業を完了します。デフォルトでは、JVMはnondaemonとしてスレッドを作成しますが、メソッドsetDaemon(true)
を使用してThreadをデーモンとして作成できます。デーモンスレッドの良い例は、すべてのnondaemonスレッドが完了するとすぐに彼の仕事を完了するGCスレッドです。
これは、ユーザスレッドが存在しないためにjvmが終了した場合のデーモンスレッドの動作をテストする例です。
以下の出力の最後の2行目に注意してください。メインスレッドが終了すると、デーモンスレッドも終了し、 最後に実行された9 finallyブロック内にステートメントを表示しませんでした。つまり、ユーザースレッドが存在しないためにJVMが終了した場合、デーモンスレッドのfinallyブロック内で閉じられた入出力リソースは閉じられません。
public class DeamonTreadExample {
public static void main(String[] args) throws InterruptedException {
Thread t = new Thread(() -> {
int count = 0;
while (true) {
count++;
try {
System.out.println("inside try"+ count);
Thread.currentThread().sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
System.out.println("finally executed"+ count);
}
}
});
t.setDaemon(true);
t.start();
Thread.currentThread().sleep(10000);
System.out.println("main thread exited");
}
}
inside try1
finally executed1
inside try2
finally executed2
inside try3
finally executed3
inside try4
finally executed4
inside try5
finally executed5
inside try6
finally executed6
inside try7
finally executed7
inside try8
finally executed8
inside try9
finally executed9
inside try10
main thread exited
デーモンスレッドは、作成者スレッドが終了すると終了します。
非デーモンスレッド(デフォルト)はメインスレッドよりも長く生きることができます。
if ( threadShouldDieOnApplicationEnd ) {
thread.setDaemon ( true );
}
thread.start();