Java之守护线程

Java之守护线程
文章图片
线程状态图 【Java之守护线程】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线程。如果一定要用,三思而后行。

    推荐阅读