13-7. デモンズレッド


Demon Thread(Daemon Thread)
通常のThread作業を支援する補助役Thread.
したがって、すべての通常のスレッドが終了すると、デーモンプロセスも自動終了を強制します.
典型的な例は、JavaのGarbage Collector(GC)および自動記憶ワードプロセッサを含む
デーモン・プロセスは、実行後に無限ループと条件文を使用して待機します.特定の条件が満たされている場合は、タスクを実行し、待機状態に戻ります.
 
作成および実行方法は、通常のねじと同じですが、作成後にsetDaemon(true)を呼び出す必要があります.
デーモンが生成したスレッドもデーモンになります.
 

  • boolean isDaemon ()
    デーモンプロセスであることを確認

  • void setDaemon (boolean on)
    特定のスレッドが呼び出されると、パラメータはtrueがデーモンスレッド、falseが通常スレッドとして指定されます.
  •  
    class DaemonThreadExample implements Runnable {
        static boolean autoSave = false;
    
        public static void main(String[] args) {
            Thread t = new Thread(new DaemonThreadExample());
            t.setDaemon(true); // 반드시 start()을 호출하기 전에 데몬 쓰레드로 지정
            t.start();
    
            for (int i = 1; i <= 10; i++) {
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {}
                System.out.println(i); // 1초마다 1부터 차례대로 10까지 숫자를 셈
    
                if (i == 5) autoSave = true; // 5가 되면 autoSave를 true로 변경
            }
        }
    
        @Override
        public void run() {
            while (true) {
                try {
                    Thread.sleep(3000);
                } catch (InterruptedException e) {}
    
                if (autoSave) autoSave(); // 3초마다 autoSave의 값을 확인해서 true면 autoSave() 호출
            }
        }
    
        public void autoSave() {
            System.out.println("Your file has been auto-saved.");
        }
    }
    1
    2
    3
    4
    5
    Your file has been auto-saved.
    6
    7
    8
    Your file has been auto-saved.
    9
    10
    約5秒後にautoSaveがtrueとなり、autoSave値のDemon Thread呼び出し条件文の自動格納メソッドのコードが3秒ごとにチェックされた.tスレッドがデーモンプロセスでない場合、mainスレッドがforゲートを迂回して終了しても、tスレッドは無限ループで実行されるため、プログラムは終了しません.tはDemon Threadなので、自分が助けたmain Threadの終了時に一緒に終了します.
    public class DaemonThreadExample2 {
        public static void main(String[] args) throws Exception {
            Thread1 t1 = new Thread1("T1");
            Thread2 t2 = new Thread2("T2");
    
            t1.start();
            t2.start();
        }
    }
    
    class Thread1 extends Thread {
        Thread1(String name) {
            super(name);
        }
    
        @Override
        public void run() {
            try {
                sleep(5000);
            } catch (InterruptedException e) {}
        }
    }
    
    class Thread2 extends Thread {
        Thread2(String name) {
            super(name);
        }
    
        @Override
        public void run() {
            Map<Thread, StackTraceElement[]> map = getAllStackTraces();
            Iterator<Thread> it = map.keySet().iterator();
    
            int x = 0;
            while (it.hasNext()) {
                Thread t = it.next();
                StackTraceElement[] ste = map.get(t);
    
                System.out.printf("[%d] name: %s, group: %s, daemon: %s%n", ++x, t.getName(), t.getThreadGroup().getName(), t.isDaemon());
    
                for (StackTraceElement el : ste) {
                    System.out.println(el);
                }
    
                System.out.println();
            }
        }
    }
    実行結果
    [1] name: Signal Dispatcher, group: system, daemon: true
    [2] name: T1, group: main, daemon: false
    [email protected]/java.lang.Thread.sleep(Native Method)
    app//Thread1.run(DaemonThreadExample2.java:22)
    [3] name: Reference Handler, group: system, daemon: true
    [email protected]/java.lang.ref.Reference.waitForReferencePendingList(Native Method)
    [email protected]/java.lang.ref.Reference.processPendingReferences(Reference.java:253)
    [email protected]/java.lang.ref.Reference$ReferenceHandler.run(Reference.java:215)
    [4] name: Common-Cleaner, group: InnocuousThreadGroup, daemon: true
    [email protected]/java.lang.Object.wait(Native Method)
    [email protected]/java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:155)
    [email protected]/jdk.internal.ref.CleanerImpl.run(CleanerImpl.java:140)
    [email protected]/java.lang.Thread.run(Thread.java:833)
    [email protected]/jdk.internal.misc.InnocuousThread.run(InnocuousThread.java:162)
    [5] name: Notification Thread, group: system, daemon: true
    [6] name: T2, group: main, daemon: false
    [email protected]/java.lang.Thread.dumpThreads(Native Method)
    [email protected]/java.lang.Thread.getAllStackTraces(Thread.java:1662)
    app//Thread2.run(DaemonThreadExample2.java:34)
    [7] name: Finalizer, group: system, daemon: true
    [email protected]/java.lang.Object.wait(Native Method)
    [email protected]/java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:155)
    [email protected]/java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:176)
    [email protected]/java.lang.ref.Finalizer$FinalizerThread.run(Finalizer.java:172)
    [8] name: Monitor Ctrl-Break, group: main, daemon: true
    [email protected]/java.util.concurrent.ConcurrentSkipListSet.(ConcurrentSkipListSet.java:114)
    [email protected]/java.net.InetAddress.(InetAddress.java:776)
    [email protected]/java.net.InetSocketAddress.(InetSocketAddress.java:229)
    [email protected]/java.net.Socket.(Socket.java:287)
    app//com.intellij.rt.execution.application.AppMainV2$1.run(AppMainV2.java:44)
     getAllStackTrace()メソッドは、動作が完了していないすべてのスレッドの呼び出しスタック情報を返す.
    タスクが完了していないスレッド==実行中または待機中のスレッド
    直接作成および実行されるT1およびT2を含む8つのスレッドが実行中または待機していることがわかる.mainスレッドはすべての作業を完了したため、実行結果に表示されずに終了して削除されました
    プログラムが実行されると、JVMは、ゴミ収集を実行するためのFinalizerと、イベント処理やグラフィック処理などのためのデーモンスレッドとを自動的に生成し、mainまたはsystemスレッドライブラリに格納する.