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

时间:2012-04-24 12:56:55

标签: java multithreading

最近我被问到一个问题:

  

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

将一个线程标记为守护进程会改变其调度吗?

4 个答案:

答案 0 :(得分:18)

  

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

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

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

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

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

答案 1 :(得分:1)

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

答案 2 :(得分:0)

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

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

答案 3 :(得分:0)

的一个例子
  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 =守护进程