Java中有两种线程,一种是守护线程,一种是用户线程。守护线程和用户线程的唯一区别就是,守护线程的死亡时间是由用户线程的生存时间决定的。只有当用户线程都结束的时候,JVM会强制停止守护线程。比如:GC线程就是典型的守护线程。
守护线程的注意点
1、设置守护线程的方式是Thread.setDeamon(true)。而且要在Thread.run()方法调用之前调用。或者说,线程启动后,不能再设置其为守护线程。
2、守护线程创建的线程也是守护线程。
3、由于守护线程的结束不掌握在自己手中,是由JVM决定的,所以要始终认识到,守护线程中的逻辑处理随时可能被打断。故,守护线程中不能放关键业务代码。比如,读写数据库,读写文件,业务处理等。我的理解,不太重要的,非关键性的处理可以放在守护线程中。要保证,即使守护线程被突然终止了,也不会影响业务逻辑的时候才可以放在守护线程中。(JVM的垃圾回收,即使失败一次,其实也不会影响业务的执行,最多也就是内存没有及时清理而已)实验
实验目的: 验证守护线程的结束不是由自己控制的,而是在没有用户线程的时候被jvm关闭的。
实验代码:
1、守护线程
// 守护线程
public static class DeamonThread implements Runnable {
public void run() {
try {
System.out.println("守护线程开始运行。");
int i = 0;
while (true) {
System.out.println("[Deamon Thread]" + i + " seconds passed.");
Thread.sleep(1000L);
I++;
}
} catch (Exception ex) {
ex.printStackTrace();
} finally {
System.out.println("守护线程结束。");
}
}
}
2、用户线程
// 用户线程
public static class UserThread implements Runnable {
public void run() {
System.out.println("用户线程开始。");
for (int i=0; i<10; i++) {
System.out.println("[User Thread]" + i + " seconds passed.");
try {
Thread.sleep(1000L);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("用户线程结束。");
}
}
3、主程序
public static void main(String[] args) {
System.out.println("start...");
//启动一个deamon线程,启动一个用户线程。用户线程启动10秒,deamon线程存活10秒。
DeamonThread dr = new DeamonThread();
Thread dt = new Thread(dr);
dt.setDaemon(true);
dt.start();
UserThread ur = new UserThread();
Thread ut = new Thread(ur);
ut.start();
System.out.println("...end");
}
4、执行结果
start...
守护线程开始运行。
[Deamon Thread]0 seconds passed.
...end
用户线程开始。
[User Thread]0 seconds passed.
[Deamon Thread]1 seconds passed.
[User Thread]1 seconds passed.
[Deamon Thread]2 seconds passed.
[User Thread]2 seconds passed.
[Deamon Thread]3 seconds passed.
[User Thread]3 seconds passed.
[Deamon Thread]4 seconds passed.
[User Thread]4 seconds passed.
[Deamon Thread]5 seconds passed.
[User Thread]5 seconds passed.
[Deamon Thread]6 seconds passed.
[User Thread]6 seconds passed.
[Deamon Thread]7 seconds passed.
[User Thread]7 seconds passed.
[Deamon Thread]8 seconds passed.
[User Thread]8 seconds passed.
[Deamon Thread]9 seconds passed.
[User Thread]9 seconds passed.
[Deamon Thread]10 seconds passed.
用户线程结束。
实验结论
在用户进程执行10秒后,守护线程也随之结束。而且显然是被jvm强制关闭的。因为守护线程中的finally语句并没有被执行。
- 使用建议
尽量不要使用deamon线程。如果一定要用,三思而后行。