在 Java 中,有两种类型的线程:

  • 守护线程
  • 用户线程

守护线程是始终在后台运行的低优先级线程,而用户线程是始终在前台运行的高优先级线程。 用户线程或非守护程序旨在执行特定或复杂的任务,其中守护程序线程用于执行支持任务。

Java中守护线程和用户线程的区别

JVM 不会等待守护线程完成,而是等待用户线程:守护线程和用户线程之间的首要区别是 JVM 不会等待守护线程完成其任务,而是等待任何活动的用户线程。
例如,在 NetBeans 中运行 Java 程序时可能已经注意到这种行为,即使主线程已经完成,左上角的向下按钮仍然是红色的,表明 Java 程序仍在运行。 这是由于从主线程产生的任何用户线程,但是对于主线程,在 NetBeans 中看不到那个红点。
Java中守护线程和用户线程的区别

  • 线程优先级:与守护线程相比,用户线程具有高优先级,这意味着它们不会像用户线程那样容易获得 CPU。
  • 创建线程:用户线程通常由应用程序创建,用于并发执行某些任务。 另一方面,守护线程主要是由 JVM 创建的,例如一些垃圾收集作业。
  • 线程终止:如果所有用户线程都已完成执行,但用户线程被应用程序或自身关闭,JVM 将强制守护线程终止。 用户线程可以通过 JVM 运行保持运行,但守护线程不能通过 JVM 保持运行。 这是用户线程和守护线程之间最关键的区别。
  • 用法:守护线程不用于任何关键任务。 任何重要的任务都由用户线程完成。 守护线程通常用于一些非关键任务的后台任务。

用户线程和守护线程的主要区别

用户线程和守护线程的主要区别如下 -

用户线程 守护线程
JVM 等到用户线程完成他们的工作。 在所有用户线程完成工作之前,它永远不会退出。 JVM 不会等待守护线程完成它们的工作。 一旦所有用户线程完成工作,JVM 就会退出。
JVM不会强制用户线程终止,所以JVM会等待用户线程自行终止。 如果所有用户线程都完成了他们的工作,JVM 将强制守护线程终止。
用户线程由应用程序创建。 主要是由 JVM 创建的守护线程。
主要是用户线程被设计来执行一些特定的任务。 守护线程被设计为支持用户线程。
用户线程是前台线程。 守护线程是后台线程。
用户线程是高优先级线程。 守护线程是低优先级线程。
它的生命独立。 它的寿命取决于用户线程。

示例:检查线程是否为守护进程

可以使用 setDaemon(boolean)方法将用户线程作为守护线程。 在此示例中,使用 isDaemon() 方法检查线程类型(用户线程或守护线程)。 如果它是守护进程,则返回 true,否则返回 false

// Java program check thread is Daemon or not

class MyThread extends Thread {

    @Override
    public void run()
    {
        System.out.println("User Thread or Non-Daemon Thread");
    }
}

class MainThread {

    public static void main(String[] args)
    {

        MyThread mt = new MyThread();
        mt.start();

        System.out.println("Main Thread");

        System.out.println("Is " + mt.getName()
                        + " a Daemon Thread: "\n                        + mt.isDaemon());

        System.out.println("Is " + Thread.currentThread().getName()
                        + " a Daemon Thread: "\n                        + Thread.currentThread().isDaemon());
    }
}

运行结果:

Main Thread
Is Thread-0 a Daemon Thread: false
Is main a Daemon Thread: false
User Thread or Non-Daemon Thread

示例:将非守护线程设为守护线程
在此示例中,使用 setDeamon(boolean) 使非守护线程成为守护线程。

// Java program make user thread as a daemon thread

class MyThread extends Thread {

    @Override
    public void run()
    {
        System.out.println("Non-Daemon thread");
    }
}

class MainThread {

    public static void main(String[] args)
    {
        MyThread mt = new MyThread();
        System.out.println("Before using setDaemon() method: ");
        System.out.println("Is " + mt.getName()
                        + " a Daemon Thread: "\n                        + mt.isDaemon());

        mt.setDaemon(true);

        System.out.println("After using setDaemon() method: ");
        System.out.println("Is " + mt.getName()
                        + " a Daemon Thread: "\n                        + mt.isDaemon());
    }
}

运行结果:

Before using setDaemon() method: 
Is Thread-0 a Daemon Thread: false
After using setDaemon() method: 
Is Thread-0 a Daemon Thread: true