java中有两种线程: ①用户线程;
②守护线程。
一、那么什么是守护线程?
对于用户线程(非守护线程),当主线程停止时,用户线程不受其影响,还可以执行,此时JVM是没有停止运行的。而守护线程是当进程不存在或主线程停止,守护线程也会被停止,JVM也就退出。其实守护线程和用户线程区别不大,可以理解为特殊的用户线程。特殊就特殊在如果程序中所有的用户线程都退出了,那么所有的守护线程就都会被杀死,很好理解,没有被守护的对象了,也不需要守护线程了。
注意: 守护线程中产生的线程都是守护线程!
JVM 程序在什么情况下能够正常退出?
The Java Virtual Machine exits when the only threads running are all daemon threads.
上面这句话来自 JDK 官方文档,意思是:
当 JVM 中不存在任何一个正在运行的非守护线程(用户线程)时,则 JVM 进程即会退出。
二、如何创建守护线程?
①普通守护线程创建
创建一个用户线程,然后调用setDaemon(true)方法将用户线程转化为守护线程
thread.setDaemon(true);
注意:必须在线程启动start()方法之前设置。
②利用Timer和TimerTask,创建守护线程
Timer是JDK提供的定时器工具,使用时会在主线程之外单独起一个线程执行指定的任务。Timer timer = new Timer()启动的是用户线程,而Timer timer = new Timer()启动的就是守护线程。TimerTask是一个实现了Runnable接口的抽象类,配合Timer使用可以看做被Timer执行的任务,即启动的线程。
public class MyTask extends TimerTask{
Override
public void run(){
//要做的任务
}
}
public class ThreadDemo2{
public static void main(String[] args) throws InterruptedException {
Calendar calendar = new Calendar.getInstance();
//当前系统时间基础上加10秒
calendar.add(Calendar.SECOND,10);
Date date = calendar.getTime();
MyTask task = new MyTask();
Timer timer = new Timer();
//当前时间10秒后执行“要做的任务”
timer.schedule(task,date);
}
}
三、守护线程应用
守护线程对于后台支持任务非常有用,例如垃圾收集,释放未使用对象的内存以及从缓存中删除不需要的条目。大多数JVM线程都是守护线程。
JVM 中的垃圾回收线程就是典型的守护线程,如果说不具备该特性,会发生什么呢?
当 JVM 要退出时,由于垃圾回收线程还在运行着,导致JVM无法退出,这样一个程序只要运行就不会退出了,由此可见,守护线程的重要性了。
通常来说,守护线程经常被用来执行一些后台任务,但是呢,你又希望在程序退出时,或者说 JVM 退出时,线程能够自动关闭,此时,守护线程是你的首选。