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