【謎解き】デーモンを守るスレッドを慎む
public class Test{
public static void main(String[] args){
int i=1;
System.out.println(" :"+i);
}
}
上記の単純なコードを実行すると、仮想マシンがプライマリスレッドを1つしか実行していないと考える人が多いです.実際にはそうではありません.仮想マシンは、ゴミ回収スレッドなどのサービススレッドを実行します.このようなスレッドは、デーモンスレッドです.
JavaにはUser Thread(ユーザスレッド)、Daemon Thread(デーモンスレッド)の2種類のスレッドがあります.
Daemonの役割は、ゴミ回収スレッドなど、他のスレッドの実行に便利なサービスを提供することです.UserとDaemonの両者はほとんど違いがなく、唯一の違いは仮想マシンの離脱にある:もしUser Threadがすべて実行を終了したら、Daemon Threadだけが存在し、仮想マシンも脱退した.守護者がいなければ、Daemonも仕事ができず、プログラムを実行する必要もありません.
なお,デーモンスレッドは仮想マシン内部のみではなく,ユーザがプログラムを作成する際に自分でデーモンスレッドを設定することも可能である.次の方法は、デーモンスレッドを設定するために使用されます.
public final void setDaemon(boolean on)
ここで注意すべき点はいくつかあります.
(1) thread.setDaemon(true)はthread.start()の前に設定しないと、IllegalThreadStateException異常が飛び出します.実行中の通常のスレッドをデーモンスレッドに設定することはできません.
(2)Daemonスレッドで生成された新しいスレッドもDaemonである.(3)すべてのアプリケーションがDaemonに割り当てられてサービスを行うことができるとは思わないでください.例えば、読み書き操作や計算ロジックなどです.
すべてのUserが完了する前に、Daemonが予想されるサービスタスクを完了したかどうかを知ることはできません.いったんUserが終了すると、大量のデータがまだ読み込まれていないか、書き出しられていない可能性があり、計算タスクが複数回実行されても結果が異なる可能性があります.これはプログラムに対して壊滅的である.この結果をもたらした理由は、すべてのUser Threadが離れると、仮想マシンも実行を終了すると述べています.
//
import java.io.*;
class TestRunnable implements Runnable{
public void run(){
try{
Thread.sleep(1000);// 1
File f=new File("daemon.txt");
FileOutputStream os=new FileOutputStream(f,true);
os.write("daemon".getBytes());
}
catch(IOException e1){
e1.printStackTrace();
}
catch(InterruptedException e2){
e2.printStackTrace();
}
}
}
public class TestDemo2{
public static void main(String[] args) throws InterruptedException
{
Runnable tr=new TestRunnable();
Thread thread=new Thread(tr);
thread.setDaemon(true); //
thread.start(); //
}
}
// : daemon.txt "daemon" 。
見たでしょう、入出力ロジックをデーモンスレッドにパッケージするのはどんなに恐ろしくて、文字列は指定ファイルに書き込まれていません.理由も簡単で、プライマリ・スレッドが完了するまで、デーモン・スレッドは1秒のブロック状態にあります.この時点でメインスレッドはすぐに実行され、仮想マシンは終了し、Daemonはサービスを停止し、出力操作は自然に失敗します.