Java中的守护线程
Java中的守护线程是一个低优先级的线程,在后台运行以执行垃圾收集等任务。 Java中的守护线程也是为用户线程提供服务的服务提供者线程。它的生命取决于用户线程的怜悯,即当所有用户线程死亡时,JVM 会自动终止该线程。
简单来说,我们可以说它为用户线程提供后台支持任务的服务。除了为用户线程服务之外,它在生活中没有任何作用。
Java 中的守护线程示例: Java中的Java收集 (gc)、终结器等。
Java守护线程的属性
- 当所有用户线程完成执行时,它们无法阻止 JVM 退出。
- 当所有用户线程完成执行时,JVM 会自行终止。
- 如果 JVM 发现一个正在运行的守护线程,它会终止该线程,然后关闭它。 JVM 并不关心 Daemon 线程是否正在运行。
- 这是一个最低优先级的线程。
守护线程的默认性质
默认情况下,主线程始终是非守护线程,但对于所有剩余线程,守护进程的性质将从父级继承到子级。也就是说,如果父进程是守护进程,子进程也是守护进程,如果父进程是非守护进程,那么子进程也是非守护进程。
Note: Whenever the last non-daemon thread terminates, all the daemon threads will be terminated automatically.
守护线程的方法
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() 方法。
守护进程与用户线程
- 优先级:当进程中仅剩的线程是守护线程时,解释器退出。这是有道理的,因为当只剩下守护线程时,没有其他线程可以为守护线程提供服务。
- 用途:守护线程是为用户线程提供后台支持任务的服务。