守护程序线程和低优先级线程之间的区别

最近我被问到一个问题:

我们有setPriority()方法来设置低优先级的线程。 那为什么我们需要一个守护程序线程。 它们之间有什么区别?

将线程标记为守护进程是否会更改其调度?

我们有setPriority()方法来设置低优先级的线程。 那为什么我们需要一个守护程序线程。 它们之间有什么区别?

通常,守护程序线程与优先级无关。 例如,在Java中,当所有用户非守护程序线程完成时,JVM将关闭。 将线程标记为守护程序线程意味着可以在JVM退出时安全地终止它。

优先级是关于调度 – 关于线程获得时间片的频率与准备运行的其他线程相比的频率。 您可以拥有低优先级守护程序线程或高优先级守护程序线程。 您可以拥有低优先级和高优先级的非守护程序线程。 顺便说一下,线程优先级仅适用于某些特定情况,当然也适用于架构和Java线程专家,我从不使用它们。

这些概念是正交的(相互独立的) – 至少在Java线程模型中是这样。

关于何时制作线程守护程序,我使用守护程序线程来执行任何我不关心的任务,如果它们在JVM退出时被中断:保持活动线程,统计处理器,日志处理等等。一切任务至关重要应用程序是一个非守护程序线程,必须特别中断或发出信号才能以某种方式退出。

正在运行的守护程序线程不会阻止程序结束/退出。 但是,所有用户线程必须在程序退出之前结束。 优先级可能适用于守护程序或用户线程。 您可以像在日常生活中理解priority一样理解priority

如果Java运行时确定应用程序中运行的唯一线程是守护程序线程(即,没有用户线程存在),Java运行时会立即关闭应用程序,从而有效地阻止所有守护程序线程在其轨道中死亡。 为了使应用程序继续运行,它必须始终至少有一个实时用户线程。 在所有其他方面,Java运行时以完全相同的方式处理守护程序线程和用户线程。

除了在守护程序线程中..当JVM突然终止然后最终块没有被执行时,堆栈没有被解开 – JVM只是退出。 由于这个原因,应该谨慎使用守护程序线程,并且将它们用于可能执行任何类型的I / O的任务是危险的。

一个例子

  1. 低优先级线程完成时JVM关闭。 尽管守护程序线程仍在运行
  2. 此外,还显示守护程序线程创建的线程自动成为守护程序线程

     package junk.daemon_thread_example; class DeamonThreadPlus implements Runnable{ String id; boolean createChild; public DeamonThreadPlus(String id, boolean createChild){ this.id = id; this.createChild = createChild; } @Override public void run() { // Parent daemon thread creates child daemon thread by default if (createChild) new Thread(new DeamonThreadPlus("DaemonChild", false)).start(); // This thread never self-completes (only terminates when process dies) while (true){ try { Thread.sleep(1); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("Daemon " + Thread.currentThread().isDaemon() + " id = " + id); } } } class UThread implements Runnable{ @Override public void run() { System.out.println("User thread start"); try { Thread.sleep(5); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("User thread end (program exits)"); } } public class Caller{ public static void main(String[] args) { Thread dt = new Thread( new DeamonThreadPlus("Daemon", true)); dt.setDaemon(true); dt.start(); Thread ut = new Thread(new UThread()); ut.setPriority(Thread.MIN_PRIORITY); ut.start(); } } 

    输出为:用户线程启动
    守护进程真正的id =守护进程
    守护进程true id = DaemonChild
    守护进程真正的id =守护进程
    守护进程true id = DaemonChild
    守护进程真正的id =守护进程
    守护进程true id = DaemonChild
    守护进程真正的id =守护进程
    守护进程true id = DaemonChild
    用户线程结束(程序退出)
    守护进程true id = DaemonChild
    守护进程真正的id =守护进程