📜  Java中的守护线程

📅  最后修改于: 2022-05-13 01:55:30.720000             🧑  作者: Mango

Java中的守护线程

Java中的守护线程是一个低优先级的线程,在后台运行以执行垃圾收集等任务。 Java中的守护线程也是为用户线程提供服务的服务提供者线程。它的生命取决于用户线程的怜悯,即当所有用户线程死亡时,JVM 会自动终止该线程。

简单来说,我们可以说它为用户线程提供后台支持任务的服务。除了为用户线程服务之外,它在生活中没有任何作用。

Java 中的守护线程示例: Java中的Java收集 (gc)、终结器等。

Java守护线程的属性

  • 当所有用户线程完成执行时,它们无法阻止 JVM 退出。
  • 当所有用户线程完成执行时,JVM 会自行终止。
  • 如果 JVM 发现一个正在运行的守护线程,它会终止该线程,然后关闭它。 JVM 并不关心 Daemon 线程是否正在运行。
  • 这是一个最低优先级的线程。

守护线程的默认性质

默认情况下,主线程始终是非守护线程,但对于所有剩余线程,守护进程的性质将从父级继承到子级。也就是说,如果父进程是守护进程,子进程也是守护进程,如果父进程是非守护进程,那么子进程也是非守护进程。

守护线程的方法

1. void setDaemon(布尔状态):

此方法将当前线程标记为守护线程或用户线程。例如,如果我有一个用户线程 tU,那么 tU.setDaemon(true) 将使它成为一个守护线程。另一方面,如果我有一个守护线程 tD,那么调用 tD.setDaemon(false) 将使它成为一个用户线程。

句法:

public final void setDaemon(boolean on)

参数:

  • on:如果为真,则将此线程标记为守护线程。

例外:

  • IllegalThreadStateException : 如果只有这个线程是活动的。
  • SecurityException:如果当前线程无法修改此线程。

2.布尔isDaemon():

此方法用于检查当前线程是否为守护进程。如果线程是 Daemon,则返回 true。否则,它返回 false。

句法:

public final boolean isDaemon()

回报:

如果此线程是守护线程,则此方法返回 true;否则为假

Java
// Java program to demonstrate the usage of
// setDaemon() and isDaemon() method.
  
public class DaemonThread extends Thread
{
    public DaemonThread(String name){
        super(name);
    }
  
    public void run()
    {
        // Checking whether the thread is Daemon or not
        if(Thread.currentThread().isDaemon())
        {
            System.out.println(getName() + " is Daemon thread");
        }
          
        else
        {
            System.out.println(getName() + " is User thread");
        }
    }
      
    public static void main(String[] args)
    {
      
        DaemonThread t1 = new DaemonThread("t1");
        DaemonThread t2 = new DaemonThread("t2");
        DaemonThread t3 = new DaemonThread("t3");
      
        // Setting user thread t1 to Daemon
        t1.setDaemon(true);
              
        // starting first 2 threads
        t1.start();
        t2.start();
  
        // Setting user thread t3 to Daemon
        t3.setDaemon(true);
        t3.start();        
    }
}


Java
// Java program to demonstrate the usage of
// exception in Daemon() Thread
  
public class DaemonThread extends Thread
{
    public void run()
    {
        System.out.println("Thread name: " + Thread.currentThread().getName());
        System.out.println("Check if its DaemonThread: "
                        + Thread.currentThread().isDaemon());
    }
  
    public static void main(String[] args)
    {
        DaemonThread t1 = new DaemonThread();
        DaemonThread t2 = new DaemonThread();
        t1.start();
          
        // Exception as the thread is already started
        t1.setDaemon(true);
          
        t2.start();
    }
}


输出:

t1 is Daemon thread
t3 is Daemon thread
t2 is User thread

守护线程中的异常

如果在启动线程后调用 setDaemon() 方法,它会抛出IllegalThreadStateException

Java

// Java program to demonstrate the usage of
// exception in Daemon() Thread
  
public class DaemonThread extends Thread
{
    public void run()
    {
        System.out.println("Thread name: " + Thread.currentThread().getName());
        System.out.println("Check if its DaemonThread: "
                        + Thread.currentThread().isDaemon());
    }
  
    public static void main(String[] args)
    {
        DaemonThread t1 = new DaemonThread();
        DaemonThread t2 = new DaemonThread();
        t1.start();
          
        // Exception as the thread is already started
        t1.setDaemon(true);
          
        t2.start();
    }
}

运行时异常:

Exception in thread "main" java.lang.IllegalThreadStateException
    at java.lang.Thread.setDaemon(Thread.java:1352)
    at DaemonThread.main(DaemonThread.java:19)

输出:

Thread name: Thread-0
Check if its DaemonThread: false

这清楚地表明我们不能在启动线程后调用 setDaemon() 方法。

守护进程与用户线程

  1. 优先级:当进程中仅剩的线程是守护线程时,解释器退出。这是有道理的,因为当只剩下守护线程时,没有其他线程可以为守护线程提供服务。
  2. 用途:守护线程是为用户线程提供后台支持任务的服务。