Java的线程分为两种,一个是用户线程,一个是守护线程。守护线程守护的对象就是用户线程,当用户线程结束后,守护它的守护线程也就会结束。二者的本质基本是一样的,唯一区别在于何时结束。

  • 用户线程:直到自己运行完或者遇到异常就结束
  • 守护线程:生命周期伴随着用户线程,随着用户线程结束而结束。

举个例子:运行状态的日志线程一般为守护线程,它时时记录运行状态的日志,守护着系统的主线程。当主线程结束或出现异常结束后,记录日志的守护线程就没有必要在记录,随着主线程结束而结束。

在java中将用户线程变为守护线程,调用setDaemon方法。

 package com.my.day01.demo05;

 public class DaemoTest {

     public static void main(String[] args) {

         Thread t = new Thread(new Runnable() {

             @Override
public void run() { try { System.out.println(Thread.currentThread().getName()+" running");
Thread.sleep(2000);
System.out.println("test");
System.out.println(Thread.currentThread().getName()+" done"); } catch (InterruptedException e) { e.printStackTrace();
}
}
});
//设置为非守护线程,随着main线程的结束,守护线程也结束
t.setDaemon(false);
t.start(); System.out.println(Thread.currentThread().getName());
} }
结果为:
main
Thread-0 running
test
Thread-0 done

在这个例子中,线程t为非守护线程,那么在main线程执行完后,线程t仍在执行。从输出的结果就可以看出来。

将线程t设为守护线程再来看一下

 package com.my.day01.demo05;

 public class DaemoTest {

     public static void main(String[] args) {

         Thread t = new Thread(new Runnable() {

             @Override
public void run() { try { System.out.println(Thread.currentThread().getName()+" running");
Thread.sleep(2000);
System.out.println("test");
System.out.println(Thread.currentThread().getName()+" done"); } catch (InterruptedException e) { e.printStackTrace();
}
}
});
//设置为守护线程,随着main线程的结束,守护线程也结束
t.setDaemon(true);
t.start(); System.out.println(Thread.currentThread().getName());
} }
结果为:
main
Thread-0 running

将线程设置为守护线程后,可以看到线程t没有运行完毕就随着main线程的结束而结束了。

再来看嵌套线程的守护线程,在main函数里面声明了一个名字叫Thread1的线程,在Thread1线程里面定义了一个名字为Thread2的线程。先将这个两个线程设为非守护线程,看结果。

 package com.my.day01.demo05;

 public class DaemoTest2 {

     public static void main(String[] args) {

         Thread t = new Thread(new Runnable() {
@Override
public void run() { Thread tt = new Thread(new Runnable() {
@Override
public void run() {
System.out.println(Thread.currentThread().getName() + "running");
try {
Thread.sleep(20_000);
} catch (InterruptedException e) { e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + "done");
} }, "Thread2"); tt.setDaemon(false);
tt.start(); System.out.println(Thread.currentThread().getName() + "running");
try { Thread.sleep(10_000); } catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + "done");
}
}, "Thread1"); // 设置为非守护线程,随着main线程的结束,守护线程也结束
t.setDaemon(false);
t.start(); System.out.println(Thread.currentThread().getName()); }
}
结果:
main
Thread1running
Thread2running
Thread1done
Thread2done

main线程执行完后,Thread2和Thread1交替执行。再来看看将子线程Thread2设为守护线程,输出的结果为

 main
Thread1running
Thread2running
Thread1done

可以看到子线程Thread2守护Thread1,当Thread1结束后,Thread2也随之结束。

如果将线程Thread1也设置为守护线程,再来看结果

main

Thread1守护的是main线程,main线程一结束Thread1也随之结束。Thread1的子线程Thread2也跟着结束(这就是说守护线程具有继承性,如果一个线程为守护线程,那么它的子线程都为守护线程)

总结:

1.守护线程守护的是它所在声明的那个线程。

2.当指定一个线程为守护线程后,它的子线程都是守护线程。

最新文章

  1. 如何用Unity创建一个的简单的HoloLens 3D程序
  2. Windows phone应用开发[18]-下拉刷新
  3. RSS阅读器python实现概述
  4. 20145337《Java程序设计》第八周学习总结
  5. 【poj1007】 DNA Sorting
  6. Nhibernate Case SUM
  7. UltraEdit 标签(tab)不见的3个解决办法
  8. HackerRank "Median Updates"
  9. C#条件编译,发布多平台和多种选择性的项目
  10. ArcGIS 坐标系统文件
  11. what are Datatypes in SQLite supporting android
  12. Kafka server的的停止
  13. Django auth 登陆后页面跳转至/account/profile,修改跳转至其他页面
  14. css区块定位之浮动与清除属性
  15. 所有的GUI Toolkit,类型之多真开眼界
  16. Linux部署ASP.NET 5 (vNext)
  17. OpenCV4Android释疑: 透析Android以JNI调OpenCV的三种方式(让OpenCVManager永不困扰)
  18. HTML条件注释
  19. ContextRefreshedEvent事件使用注意事项(Spring)
  20. mysql一些常用配置

热门文章

  1. 电子书及阅读器Demo
  2. thymeleaf模板引擎简介
  3. HD Tune检查硬盘各参数的含义
  4. dubbo的dispatcher设置原理
  5. 「HAOI2011」Problem c
  6. 2019年 我的phper之路,时光没了,头发还在
  7. C/C++网络编程4——实现基于TCP的服务器端/客户端1
  8. js 常用字符正则匹配
  9. shell coding about mac ox
  10. char、pchar、string互相转换