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

谁能告诉我Java中有哪些守护进程线程?

524592 次浏览

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

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

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

Java中的守护线程是不阻止JVM退出的线程。具体来说,当只剩下守护线程时,JVM将退出。您可以通过调用Thread上的setDaemon()方法来创建一个。

读一读守护进程线程

守护进程线程是一个线程,它被认为在后台执行一些任务,例如处理请求或应用程序中可能存在的各种时间作业。

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

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

还有几点(参考:Java实践中的并发

  • 当一个新线程被创建时,它会继承它的守护进程状态父。
  • 当所有非守护线程完成时,JVM停止,任何剩余的守护进程线程被放弃

    • 最后块不被执行
    • 堆栈没有展开-JVM只是退出。

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

守护程序线程和用户线程。通常程序员创建的所有线程都是用户线程(除非您指定它是守护程序或您的父线程是守护程序线程)。用户线程通常是为了运行我们的程序代码。除非所有用户线程都终止,否则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}}}}

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

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

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

setDaemon(true/false)?此方法用于指定线程是守护进程线程。

公共布尔值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");}
}

输出:

C:\java\thread>javac DaemonThread.java
C:\java\thread>java DaemonThreadEntering main MethodEntering run methodIn run Method: currentThread() isThread[Thread-0,5,main]In run method: woke up againIn run method: woke up againIn run method: woke up againIn run method: woke up againIn run method: woke up againIn run method: woke up againLeaving main method
C:\j2se6\thread>

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

守护进程线程就像大家解释的那样,不会限制JVM退出,所以从退出的角度来看,它基本上是一个快乐的应用程序线程。

想要补充的是,当我提供一个API,比如将数据推送到第三方服务器/或JMS时,可以使用守护线程,我可能需要在客户端JVM级别聚合数据,然后在单独的线程中发送到JMS。如果这不是必须推送到服务器的数据,我可以将此线程作为守护线程。这种数据类似于日志推送/聚合。

问候,马尼什

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

注意事项:

  1. 由主线程创建的任何线程,在Java中运行main方法,默认情况下是非守护进程,因为Thread从创建它的线程(即父线程)继承其守护进程性质,并且由于主线程是非守护进程线程,因此从它创建的任何其他线程将保持非守护进程,直到通过调用setDaemon(true)显式制作守护进程。

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

Java中Daemon和非Daemon线程的区别:

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

2)当JVM终止时,Daemon Thread与User Thread的处理方式不同,最后不调用块,堆栈并非没有受伤,JVM只是退出。

Java有一种特殊的线程,称为守护进程线程。

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

守护进程线程用于什么?

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

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

还有更多…

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

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

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

守护进程线程类似于守护进程,负责管理资源,守护进程线程由JavaVM创建以服务于用户线程。示例更新系统为unix,unix是守护进程。守护进程线程的子线程始终是守护进程线程,因此默认情况下守护进程是false.you可以使用"isDaemon()"方法将线程检查为守护进程或用户。所以守护线程或守护进程基本上负责管理资源。例如,当您启动jvm时,正在运行垃圾收集器,即优先级为1的守护进程线程,这是最低的,它正在管理内存。只要用户线程还活着,jvm就活着,u不能杀死守护进程thread.jvm负责杀死守护进程线程。

守护进程:d(isk)一个(nd)e(执行)(itor)或从de(副)(itor)

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

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

来源:牛津词典英语

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

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

我想澄清一个误解:

  • 假设如果守护进程线程(例如B)在用户线程中创建(例如A);则此用户线程/父线程(A)的结束不会结束它创建的守护线程/子线程(B);提供用户线程是唯一的一个正在运行。
  • 因此,线程结束时没有父子关系。一旦没有单个活动用户线程并导致JVM终止,所有守护进程线程(无论它在哪里创建)都将结束。
  • 即使对于两个(父/子)都是守护进程线程也是如此。
  • 如果从守护线程创建的子线程也是守护线程。这不需要任何显式的守护线程标志设置。类似地,如果从用户线程创建的子线程也是用户线程,如果要更改它,则需要在该子线程开始之前设置显式守护进程标志。

在Java,守护进程线程是不阻止虚拟机(JVM)退出Java线程类型之一。守护线程的主要目的是执行后台任务,特别是在一些常规周期性任务或工作的情况下。随着JVM退出,守护线程也会死亡。

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

对我来说,守护进程线程就像用户线程的看门人。如果所有用户线程都已完成,则守护进程线程没有作业并且被JVM杀死。我在YouTube视频中解释过。

让我们只在带有工作示例的代码中交谈。我喜欢Russ上面的答案,但为了消除我的任何疑问,我对它进行了一点增强。我运行了两次,一次将工作线程设置为deamon true(deamon线程),另一次将其设置为false(用户线程)。它确认主线程终止时deamon线程结束。

public class DeamonThreadTest {
public static void main(String[] args) {
new WorkerThread(false).start();    //set it to true and false and run twice.
try {Thread.sleep(7500);} catch (InterruptedException e) {// handle here exception}
System.out.println("Main Thread ending");}}
class WorkerThread extends Thread {
boolean isDeamon;
public WorkerThread(boolean isDeamon) {// 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.this.isDeamon = isDeamon;setDaemon(isDeamon);}
public void run() {System.out.println("I am a " + (isDeamon ? "Deamon Thread" : "User Thread (none-deamon)"));
int counter = 0;
while (counter < 10) {counter++;System.out.println("\tworking from Worker thread " + counter++);
try {sleep(5000);} catch (InterruptedException e) {// handle exception here}}System.out.println("\tWorker thread ends. ");}}


result when setDeamon(true)=====================================I am a Deamon Threadworking from Worker thread 0working from Worker thread 1Main Thread ending
Process finished with exit code 0

result when setDeamon(false)=====================================I am a User Thread (none-deamon)working from Worker thread 0working from Worker thread 1Main Thread endingworking from Worker thread 2working from Worker thread 3working from Worker thread 4working from Worker thread 5working from Worker thread 6working from Worker thread 7working from Worker thread 8working from Worker thread 9Worker thread ends.
Process finished with exit code 0

守护线程通常被称为“服务提供者”线程。这些线程不应用于执行程序代码,而应用于执行系统代码。这些线程与您的代码并行运行,但JVM可以随时杀死它们。当JVM发现没有用户线程时,它会停止它,所有守护线程立即终止。我们可以使用以下方法将非守护线程设置为守护进程:

setDaemon(true)

守护进程线程就像助手。非守护进程线程就像前面的表演者。助手帮助表演者完成一项工作。当工作完成时,表演者不再需要帮助来执行。由于不需要帮助,助手离开了这个地方。所以当非守护进程线程的工作结束时,守护进程线程就离开了。

JVM将在最后一个非守护进程线程执行完成时完成工作。默认情况下,JVM将创建一个线程作为非守护进程,但我们可以在方法setDaemon(true)的帮助下将Thread作为守护进程。守护进程线程的一个很好的例子是GC线程,它将在所有非守护进程线程完成后立即完成他的工作。

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

请注意下面输出中的倒数第二行,当主线程退出时,守护程序线程也死了,并且没有在最终块中打印最终执行9语句。这意味着如果JVM由于用户线程不存在而退出,则守护程序线程的最终块中关闭的任何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 blocke.printStackTrace();} finally {System.out.println("finally executed"+ count);}}});t.setDaemon(true);t.start();
Thread.currentThread().sleep(10000);System.out.println("main thread exited");}}

产出

inside try1finally executed1inside try2finally executed2inside try3finally executed3inside try4finally executed4inside try5finally executed5inside try6finally executed6inside try7finally executed7inside try8finally executed8inside try9finally executed9inside try10main thread exited

已经有很多答案;然而,也许我可以更清楚地说明这一点,因为当我读到守护进程线程时,最初,我有一种感觉,我很好地理解它;然而,在玩了它并调试了一下之后,我观察到一种奇怪的(对我来说)行为。

我被教导说:

如果我希望主线程有序完成执行后线程立即死亡,我应该将其设置为Diamond。

我尝试了什么:

  • 我从Main Thread创建了两个线程,我只将其中的一个设置为diamond
  • 在有序完成Main Thread这些新创建的线程都没有退出的执行之后,但我预计,Daemon线程应该已经退出;
  • 我浏览了许多博客和文章,到目前为止,我找到的最好和最清晰的定义来自Java并发实践书,它非常清楚地指出:

7.4.2守护进程线程

有时你想创建一个执行一些辅助程序的线程函数,但您不希望此线程的存在阻止JVM关闭。这就是守护线程的用途。线程分为两种类型:普通线程和守护线程。当JVM启动时,它创建的所有线程(例如垃圾)收集器和其他内务线程)是守护线程,除了主线程。创建新线程时,它继承守护进程创建它的线程的状态,因此默认情况下任何线程主线程创建的也是普通线程。正常线程和守护进程线程仅在它们退出时发生的事情上有所不同。当一个线程退出,JVM执行正在运行的线程的清单,如果唯一剩下的线程是守护线程,它启动一个有序关闭。当JVM停止时,任何剩余的守护进程线程都将废弃-最后块不执行,堆栈不展开-JVM刚刚退出。应谨慎使用守护进程线程-很少处理活动可以随时安全地放弃,无需清理。在特别是,将守护进程线程用于可能会导致执行任何类型的I/O。守护进程线程最好保存为“内务”任务,例如定期执行的后台线程从内存缓存中删除过期条目。

  • 守护线程是为用户线程提供一般服务的线程(例如:清理服务-垃圾收集器)
  • 守护进程线程一直在运行,直到被JVM杀死
  • 当JVM终止时,守护进程线程与用户线程的处理方式不同,最后块不被称为JVM只是退出
  • 除非所有用户线程都终止,否则JVM不会终止。如果所有用户线程都死了,JVM会终止
  • 在不调用现有和最终块之前,JVM不会等待任何守护进程线程完成
  • 如果所有用户线程都死了,JVM会在停止之前杀死所有守护线程
  • 当所有用户线程都终止时,守护线程也可以终止,主程序也会终止
  • 必须在调用线程的start()方法之前调用setDaemon()方法
  • 一旦线程开始执行,它的守护进程状态就不能改变
  • 要确定一个线程是否是守护进程线程,请使用访问器方法isDaemon()

Java守护进程线程

[守护进程]

Java使用user threaddaemon tread概念。

jvm流

1. If there are no `user treads` JVM starts terminating the program2. JVM terminates all `daemon threads` automatically without waiting when they are done3. JVM is shutdown

如你所见,daemon treaduser treads服务线程

  • daemon tread是低优先级线程。
  • 线程从父线程继承它的属性。要在外部设置它,您可以使用setDaemon()方法之前启动它或通过isDaemon()检查它

守护进程线程

在后台运行的线程称为守护线程。

守护进程线程示例:

  1. 垃圾收集器。
  2. 信号调度员。

守护进程线程的目标:

守护线程的主要目标是为非守护线程提供支持。

有关Daemon线程的其他信息:

  1. 通常,守护线程在MIN_PRIORITY中运行,但是也可以在MAX_PRIORITY中运行守护线程。

    示例:通常GC以MIN_PRIORITY优先级运行,但是,一旦需要额外的内存。JVM将GC的优先级从MIN_PRIORITY增加到MAX_PRIORITY



  1. 一旦线程启动,它就不能从守护进程线程更改为非守护进程线程,这将导致IllegalThreadStateException

    示例:

    public static void main(String[] args) {Thread.currentThread().setDaemon(true);}

    输出:

    Exception in thread "main" java.lang.IllegalThreadStateExceptionat java.base/java.lang.Thread.setDaemon(Thread.java:1403)


  1. 如果我们分支一个线程,子线程继承父线程的性质。如果父线程是非守护进程线程,子线程也将自动是非守护进程,如果父线程是守护进程,子线程也将是守护进程。

    class Scratch {public static void main(String[] args) {CustomThread customThread = new CustomThread();customThread.start();}}class CustomThread extends Thread{@Overridepublic void run() {System.out.println(currentThread().isDaemon());}}

    输出:

     false


  1. 当最后一个非守护线程终止时,所有守护线程都会自动终止。

    class Scratch {public static void main(String[] args) {System.out.println("Main Thread Started.");
    CustomThread customThread = new CustomThread();customThread.setDaemon(true);customThread.start();
    System.out.println("Main Thread Finished.");}}class CustomThread extends Thread{@Overridepublic void run() {System.out.println("Custom Thread Started.");try {sleep(2000);} catch (InterruptedException ignore) {}System.out.println("Custom Thread Finished.");  //Won't get executed.}}

    输出:

    Main Thread Started.Main Thread Finished.Custom Thread Started.

Java线程中的用户线程与守护进程线程

  • 守护进程线程

Java中的线程是低优先级线程,在后台运行以执行垃圾回收机制等任务。Java中的守护进程线程也是服务提供者线程,为用户线程提供服务。

  • 用户线程

这些线程是高优先级线程。JVM将等待任何用户线程完成其任务,然后再终止它

"请记住用户和守护进程线程都包装在OS线程上"

最近OpenJdk在项目织机中提出了虚拟线程(它们也是基于用户的),您可以在FibersContinuations中找到更多关于这里中Java虚拟机线程的信息。