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


当前回答

守护线程类似于助手线程。非daemon线程就像前面的表演者。助手帮助表演者完成一项工作。工作完成后,执行者不再需要帮助来执行。由于不需要帮助,助手们离开了这个地方。因此,当非守护线程的任务结束时,守护线程就会离开。

其他回答

我想澄清一个误解:

Assume that if daemon thread (say B) is created within user thread (say A); then ending of this user thread/parent thread (A) will not end the daemon thread/child thread (B) it has created; provided user thread is the only one currently running. So there is no parent-child relationship on thread ending. All daemon threads (irrespective of where it is created) will end once there is no single live user thread and that causes JVM to terminate. Even this is true for both (parent/child) are daemon threads. If a child thread created from a daemon thread then that is also a daemon thread. This won't need any explicit daemon thread flag setting. Similarly if a child thread created from a user thread then that is also a user thread, if you want to change it, then explicit daemon flag setting is needed before start of that child thread.

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()

守护线程就像一个服务提供者,为运行在与守护线程相同进程中的其他线程或对象提供服务。守护线程用于后台支持任务,只有在正常线程执行时才需要守护线程。如果正常线程不运行,其余线程是守护线程,则解释器退出。

例如,HotJava浏览器使用最多4个名为“Image Fetcher”的守护线程从文件系统或网络中为任何需要的线程获取图像。

守护线程通常用于为应用程序/applet执行服务(例如加载“fiddley bits”)。用户线程和守护线程之间的核心区别在于,JVM只会在所有用户线程都终止时关闭程序。当不再有任何用户线程在运行(包括执行主线程)时,守护线程将由JVM终止。

setDaemon(真/假)?此方法用于指定一个线程是守护线程。

公共boolean isDaemon() ?此方法用于确定线程是否是守护线程。

Eg:

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>

java线程中的用户线程与守护线程

守护进程的线程

这些线程在Java中是低优先级的线程,在后台运行以执行诸如垃圾收集之类的任务。Java中的守护线程也是一个服务提供者线程,它向用户线程提供服务。

用户线程

这些线程是高优先级线程。JVM将等待任何用户线程在终止它之前完成它的任务

“请记住用户和守护线程都包装在操作系统线程上”

最近OpenJdk在Loom项目中提出了虚拟线程(它们也是基于用户的),你可以在这里找到更多关于Java虚拟机线程的纤维和延续。

下面是一个示例,用于测试在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