有人能告诉我Java中的守护线程是什么吗?


当前回答

Daemon threads are those threads which provide general services for user threads (Example : clean up services - garbage collector) Daemon threads are running all the time until kill by the JVM Daemon Threads are treated differently than User Thread when JVM terminates , finally blocks are not called JVM just exits JVM doesn't terminates unless all the user threads terminate. JVM terminates if all user threads are dies JVM doesn't wait for any daemon thread to finish before existing and finally blocks are not called If all user threads dies JVM kills all the daemon threads before stops When all user threads have terminated, daemon threads can also be terminated and the main program terminates setDaemon() method must be called before the thread's start() method is invoked Once a thread has started executing its daemon status cannot be changed To determine if a thread is a daemon thread, use the accessor method isDaemon()

其他回答

下面是一个示例,用于测试在jvm由于不存在用户线程而退出时守护线程的行为。

请注意下面输出的倒数第二行,当主线程退出时,守护线程也死了,并且没有在finally块中打印finally executed9语句。这意味着如果由于不存在用户线程而导致JVM退出,守护线程finally块内关闭的任何i/o资源都不会被关闭。

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

守护线程是在进程的其他非守护线程仍在运行时在后台运行的线程。因此,当所有非守护进程线程完成时,守护进程线程将终止。非守护进程线程的一个例子是运行Main的线程。 通过在线程启动之前调用setDaemon()方法,将线程设置为守护进程

更多参考:Java中的守护进程线程

守护线程和用户线程。通常程序员创建的所有线程都是用户线程(除非你指定它为守护线程或者你的父线程是守护线程)。用户线程通常用于运行我们的程序代码。除非所有用户线程都终止,否则JVM不会终止。

以上答案都是好的。下面是一个简单的小代码片段,以说明两者的区别。在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 non daemon thread),
        // the WorkerThread continues to run.
        // When true, (i.e. when it's a daemon thread),
        // the WorkerThread terminates when the main 
        // thread or/and user defined thread(non daemon) 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
            }
        }
    }
}

Java中的守护线程是指运行在后台的线程,主要由JVM创建,用于执行后台任务,如垃圾收集和其他家政任务。

注意事项:

Any thread created by main thread, which runs main method in Java is by default non daemon because Thread inherits its daemon nature from the Thread which creates it i.e. parent Thread and since main thread is a non daemon thread, any other thread created from it will remain non-daemon until explicitly made daemon by calling setDaemon(true). Thread.setDaemon(true) makes a Thread daemon but it can only be called before starting Thread in Java. It will throw IllegalThreadStateException if corresponding Thread is already started and running.

Java中守护线程与非守护线程的区别:

1) JVM在存在之前不会等待任何守护线程完成。

2)当JVM终止时,守护线程与用户线程被区别对待,最终块不被调用,堆栈不受伤,JVM只是退出。