守护线程

所谓守护线程可以理解为后台线程,用户线程理解为前台线程,那么后台线程依赖前台线程。
当前台线程远行结束后,后台线程自动结束,不管后台线程是不是无限循环。
守护线程地位比用户线程底,用户线程退出后,就会随JVM线程退出,而不管工作是否完成!!!

java中有两种线程:

  1. 用户线程(User Thread)
  2. 守护线程(Daemon Thread)
    比如GC垃圾回收线程,这个线程具有最低的优先级。

两者几乎没有区别,唯一的不同之处就在于虚拟机的离开:

如果用户线程全部退出离开,只剩下守护线程,虚拟机就会退出。
如果还有至少一个用户线程,那么虚拟机就不会退出。

别急大白话在下面。

守护线程有什么用

守护线程的目的是守护其他线程、守护其他线程、守护其他线程!!!
守护线程的目的就是:为其他线程服务的线程
所以守护线程需要有被守护的线程!!!

说这么多,跟普通线程到底有什么区别,不还是一个用户创建的线程?

区别在于:

  1. 用户线程退出,守护线程立即结束
    这个和普通线程可不一样,一般情况下,普通线程在main线程结整后,依然会运行直到任务结束,可以自行实验。
    守护线程不一样,只要用户线程退出,就立马退出,不管三七二一。
  2. 在Daemon线程中产生的新线程也是Daemon的

说白了就是其他线程的小妾,随他生,随他死,地位又低,连把话说完的机会都没有,就不配叫守护线程,应该叫小妾线程。

测试类

守护线程,必须在线程启动前调用 setDeamon 方法,则线程成为守护线程。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
public class Test {
public static void main(String[] args) {
StopThread s = new StopThread();
Thread t1 = new Thread(s);
Thread t2 = new Thread(s);
//设置为守护进程
t1.setDaemon(true);
t2.setDaemon(true);
t1.start();
t2.start();
int num = 0;
while (true) {
System.out.println(Thread.currentThread().getName() + "----" + num);
if (num++ == 60) {
break;
}
}
//验证自己是否为守护线程
//t1.isDaemon();
}
}

public class StopThread implements Runnable {

private boolean flag = true;

@Override
public synchronized void run() {
while (flag) {
System.out.println(Thread.currentThread().getName() + "...run");
}
System.out.println("...stop");
}
}

什么时候用

比如在有一个用户线程,进行定时查询,创建业务线程时,再创建一个守护线程,专门用来统计每次查询耗时,这个线程唯一的做用就是服务这个查询线程。
如果查询线程退出了,它也没必要存在了,也不影响业务。

用户线程提供某些服务或支持时,在任何情况下,用户线程结束这个服务需要立刻停止的情况下。比如有用户操作就起一个守护线程执行备份操作。若所有用户线程都退出了,守护线程自动退出,就没必要再备份了。

在守护线程中,编写代码要注意:守护线程不能持有任何需要关闭的资源,例如打开文件等,因为虚拟机退出时,守护线程没有任何机会来关闭文件,这会导致数据丢失。