最近有人问我一个问题:
我们已经有了将
setPriority()
线程设置为低优先级的方法。那为什么我们需要一个守护线程。他们之间有什么区别?
将线程标记为守护进程会改变它的调度吗?
最近有人问我一个问题:
我们已经有了将
setPriority()
线程设置为低优先级的方法。那为什么我们需要一个守护线程。他们之间有什么区别?
将线程标记为守护进程会改变它的调度吗?
我们有 setPriority() 方法将线程设置为低优先级。那为什么我们需要一个守护线程。他们之间有什么区别?
通常,守护线程与优先级无关。当所有用户非守护线程完成时,JVM 将关闭。将线程标记为守护线程意味着它可以在 JVM 退出时被安全地杀死。
优先级与调度有关——与其他准备运行的线程相比,一个线程获得时间片的频率。您可以拥有低优先级守护线程或高优先级守护线程。您可以拥有低优先级和高优先级的非守护线程。顺便说一句,线程优先级仅适用于某些特定情况和某些架构,作为 Java 线程专家,我从不使用它们。
这些概念是正交的(相互独立的)——至少在 Java 线程模型中是这样。
至于何时创建线程守护进程,我将守护线程用于任何我不在乎它们是否在 JVM 退出时被中断的任务:保持活动线程、统计处理器、日志处理等。应用程序是一个非守护线程,必须特别中断或发出信号以某种方式退出。
正在运行的守护线程不会阻止您的程序结束/退出。但是,所有用户线程必须在您的程序退出之前结束。优先级可能适用于守护进程或用户线程。您可能会priority
像在日常生活中那样理解它。
一个例子
ALSO,显示由守护线程创建的线程自动成为守护线程
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();
}
}
输出为: User thread start
Daemon true id = Daemon
Daemon true id = DaemonChild
Daemon true id = Daemon
Daemon true id = DaemonChild
Daemon true id = Daemon
Daemon true id = DaemonChild
Daemon true id = Daemon
Daemon true id = DaemonChild
User thread end (程序退出)
Daemon true id = DaemonChild
Daemon true id = Daemon
如果 Java 运行时确定应用程序中运行的唯一线程是守护线程(即不存在用户线程),Java 运行时会立即关闭应用程序,从而有效地阻止所有死在其轨道上的守护线程。为了让应用程序继续运行,它必须始终具有至少一个活动用户线程。在所有其他方面,Java 运行时以完全相同的方式处理守护线程和用户线程。
除了在守护线程中......当 JVM 突然终止时,finally 块不会被执行,堆栈不会被展开——JVM 只是退出。由于这个原因,应该谨慎使用守护线程,并且将它们用于可能执行任何类型 I/O 的任务是很危险的。