什么是Java中的守护程序线程?

roc*_*ker 770 java multithreading

任何人都能告诉我Java中的守护程序线程是什么吗?

b_e*_*erb 604

守护程序线程是一个线程,它不会阻止JVM在程序完成但程序仍在运行时退出.守护程序线程的一个示例是垃圾回收.

您可以在线程启动之前使用该setDaemon(boolean)方法更改Thread守护程序属性.

  • 对于后代,只能在线程启动之前调用`setDamon(boolean)`.默认情况下,线程继承其父线程的守护程序状态. (205认同)
  • @Gerald,*JVM退出时会杀死所有*线程.B_erb说,"...当程序结束时." 这意味着,如果程序没有显式地终止JVM,那么当最后一个_non_-daemon线程结束时,JVM将自动终止自身.正常线程定义"程序何时退出".守护程序线程没有. (19认同)
  • 所以这行`线程在程序完成但线程仍在运行时不会阻止JVM退出`基本上意味着启动线程的JVM进程并不关心守护线程是否完成执行,它只会结束如果所有正常线程都执行完毕,则自行执行。 (4认同)
  • “当程序完成但线程仍在运行时,不会阻止 JVM 退出”,而 @sateesh 则表示“JVM 会停止任何剩余的守护线程并被放弃”。那么当 JVM 退出时,守护线程会结束运行吗? (2认同)
  • @Gray很高兴知道这个..但小东西setDaemon(布尔)...'e'错过了. (2认同)
  • @SolomonSlow 当 JVM 结束时,杀死仍在执行其工作的守护线程(例如垃圾收集器)会产生什么后果?谢谢。 (2认同)

sat*_*esh 333

还有几点(参考:Java Concurrency in Practice)

  • 创建新线程时,它会继承其父级的守护程序状态.
  • 当所有非守护程序线程完成时,JVM将停止,并且任何剩余的守护程序线程都将被放弃:

    • 最后块没有被执行,
    • 堆栈没有解开 - JVM刚刚退出.

    由于这个原因,应该谨慎使用守护程序线程,并且将它们用于可能执行任何类型的I/O的任务是危险的.

  • 第二点是胡说八道.当JVM停止时,*所有*线程都会死掉,并且不会执行`finally`块,无论线程是否是守护进程.因此,如果您认为可能正在运行线程进行I/O,请不要调用`System.exit(...)`.唯一的区别是当只剩下守护进程线程时,JVM将触发自己的终止. (50认同)
  • 什么是"堆栈没有解开"? (10认同)
  • 为什么不应该将守护程序线程用于I/O?是否关注BufferedWriters等未被刷新? (3认同)
  • @PaulCager是的,他们也可以在写/读中间切断膝盖. (3认同)
  • @ɢʜʘʂʈʀɛɔʘɴ有关于"展开堆栈"的一些解释,包括这个:http://flylib.com/books/en/2.254.1.277/1/ (2认同)

小智 175

以上所有答案都很好.这是一个简单的小代码片段,用于说明差异.尝试使用true和false中的每个值setDaemon.

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
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

  • @russ好的代码段!我不得不将WorkerThread类定义为静态。 (2认同)

cle*_*tus 95

传统上,UNIX中的守护进程是那些在后台不断运行的进程,就像Windows中的服务一样.

Java中的守护程序线程不会阻止JVM退出.特别是当只剩下守护程序线程时,JVM将退出.您可以通过调用setDaemon()方法来创建一个Thread.

阅读守护程序线程.

  • 你的链接在这个时间点已经死了,也许你想要更新?无论如何,给你+1. (3认同)
  • 我喜欢UNIX和Windows之间的比较. (2认同)

Okk*_*kky 57

守护程序线程就像是与守护程序线程在同一进程中运行的其他线程或对象的服务提供者.守护程序线程用于后台支持任务,仅在正常线程执行时才需要.如果正常线程未运行且剩余线程是守护程序线程,则解释器退出.

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

守护程序线程通常用于为您的应用程序/ applet执行服务(例如加载"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");
    }

}
Run Code Online (Sandbox Code Playgroud)

输出:

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>
Run Code Online (Sandbox Code Playgroud)


Pre*_*raj 34

守护进程(计算)的定义:

后台进程处理服务请求,如打印假脱机和文件传输,并在不需要时处于休眠状态.

- 来源:Oxford Dictionaries的英文

什么是Java中的守护程序线程?

  • 守护程序线程可以在它们的流,Non-Daemon之间的任何时间关闭,即用户线程完全执行.
  • 守护程序线程以低优先级执行.
  • 守护程序线程是在后台间歇运行的线程,只要其他非守护程序线程正在运行.
  • 当所有非守护程序线程完成时,守护程序线程将自动终止.
  • 守护程序线程是在同一进程中运行的用户线程的服务提供者.
  • JVM不关心守护进程线程在运行状态下完成,甚至不是finally块也让let执行.JVM确实优先考虑由我们创建的非守护程序线程.
  • 守护程序线程在Windows中充当服务.
  • 当所有用户线程(与守护程序线程相反)终止时,JVM会停止守护程序线程.因此,守护程序线程可用于实现,例如,监视功能,因为一旦所有用户线程都停止,JVM就会停止线程.

  • 守护程序线程以与其创建线程相同的优先级执行,除非它在启动之前已被更改.守护程序线程不一定是"服务提供者"或Windows服务或此处所述的任何其他内容:它们只是不阻止JVM退出的线程.期. (5认同)

Jac*_*ack 33

一个守护线程是被认为做了一些任务,这样可以在应用程序中存在处理请求或各种chronjobs后台线程.

当您的程序只剩下守护程序线程时,它将退出.这是因为通常这些线程与普通线程一起工作并提供事件的后台处理.

您可以使用方法指定a Thread守护进程setDaemon,它们通常不会退出,也不会被中断..它们只是在应用程序停止时停止.


Kan*_*mar 15

我想澄清一个误解:

  • 假设在用户线程(例如A)中创建了守护程序线程(比如说B); 然后结束此用户线程/父线程(A)将不会结束它创建的守护程序线程/子线程(B); 提供的用户线程是当前唯一运行的线程.
  • 所以在线程结束时没有父子关系.一旦没有单个实时用户线程并且导致JVM终止,所有守护程序线程(无论它在何处创建)都将结束.
  • 即使是(父/子)都是守护进程线程也是如此.
  • 如果从守护程序线程创建的子线程,那么它也是一个守护程序线程.这不需要任何显式守护程序线程标志设置.类似地,如果从用户线程创建的子线程然后也是用户线程,如果要更改它,则在启动该子线程之前需要显式守护程序标志设置.


小智 12

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


小智 10

Java有一种叫做守护程序线程的特殊线程.

  • 优先级很低.
  • 仅在没有运行同一程序的其他线程时执行.
  • 当守护程序线程是程序中运行的唯一线程时,JVM结束程序完成这些线程.

什么是守护程序线程用于?

通常用作普通线程的服务提供者.通常有一个等待服务请求或执行线程任务的无限循环.他们不能做重要的工作.(因为我们不知道他们什么时候会有CPU时间,如果没有其他线程在运行,他们可以随时完成.)

这种线程的典型示例是Java垃圾收集器.

还有更多...

  • 您只能在调用setDaemon()方法之前调用该start()方法.线程运行后,您无法修改其守护程序状态.
  • 使用isDaemon()方法检查线程是守护程序线程还是用户线程.

  • -1,我不相信守护程序线程本质上是低优先级的.当然没有我见过的文件说明这样的.此SO回答声称优先级和守护进程是正交的:http://stackoverflow.com/a/10298353/839128 (8认同)
  • 守护程序线程与优先级无关.您可以拥有高优先级守护程序线程或低优先级非守护程序线程. (5认同)

Har*_*ngh 8

守护程序线程就像助手.非守护进程线程就像前面的表演者.助理帮助表演者完成一份工作.作业完成后,表演者不再需要帮助.由于不需要任何帮助,助理离开了这个地方.因此,当非守护程序线程的作业结束时,守护程序线程就会消失.


Cha*_*kag 5

守护程序线程就像普通线程一样,只是当其他非守护程序线程不存在时,JVM才会关闭.守护程序线程通常用于为您的应用程序执行服务.


Ani*_*kur 5

Java中的守护程序线程是那些在后台运行的线程,主要由JVM创建,用于执行垃圾收集和其他内务处理任务等后台任务.

注意事项:

  1. 由主线程创建的任何线程(在Java中运行main方法)默认为非守护进程,因为Thread从创建它的Thread继承其守护进程性质,即父线程,因为主线程是非守护进程线程,从它创建的任何其他线程将在通过调用setDaemon(true)显式创建守护进程之前,保持非守护进程.

  2. Thread.setDaemon(true)创建一个Thread守护进程但只能在启动Thread中的Java之前调用它.如果相应的Thread已经启动并运行,它将抛出IllegalThreadStateException.

Java中守护程序和非守护程序线程之间的区别:

1)JVM不会等待任何守护程序线程在现有之前完成.

2)当JVM终止时,守护进程线程的处理方式与用户线程不同,最后不会调用块,堆栈不会被解除,JVM就会退出.


小智 5

在Java中,守护程序线程是不会阻止Java虚拟机(JVM)退出的线程类型之一。守护程序线程的主要目的是执行后台任务,尤其是在某些例行定期任务或工作的情况下。随着JVM退出,守护程序线程也消失了。

通过设置a thread.setDaemon(true),线程成为守护程序线程。但是,只能在线程启动之前设置此值。


小智 5

这是一个示例,用于在由于用户线程不存在而导致jvm退出的情况下测试守护程序线程的行为。

请注意下面输出中的倒数第二行,当主线程退出时,守护程序线程也死了,并且在finally块中没有打印finally execute9语句。这意味着,如果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");
  }
}
Run Code Online (Sandbox Code Playgroud)

输出量

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
Run Code Online (Sandbox Code Playgroud)