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.当指定一个线程为守护线程后,它的子线程都是守护线程。

Java多线程编程之守护线程的更多相关文章

  1. java并发编程学习: 守护线程(Daemon Thread)

    在正式理解这个概念前,先把 守护线程 与 守护进程 这二个极其相似的说法区分开,守护进程通常是为了防止某些应用因各种意外原因退出,而在后台独立运行的系统服务或应用程序. 比如:我们开发了一个邮件发送程 ...

  2. java 多线程8(守护线程)

    比如:后台偷偷运行的那些,qq下载更新包 如果一个进程中只剩下了守护线程,那么守护线程也会死亡.. 一个线程默认都不是守护线程. 判断是否是守护线程:例:d.isDaemon(); 当一个线程随着你的 ...

  3. JAVA多线程学习六-守护线程

    java中的守护程序线程是一个服务提供程序线程,它为用户线程提供服务. 它的生命依赖于用户线程,即当所有用户线程都死掉时,JVM会自动终止该线程. 有许多java守护程序线程自动运行,例如 gc,fi ...

  4. java多线程编程(二创建线程)

    1.概念           因为java是完全面向对象的,所以在java中,我们说的线程,就是Thread类的一个实例对象.所以,一个线程就是一个对象,它有自己字段和方法. 2.创建线程 创建线程有 ...

  5. Java多线程编程(1)--Java中的线程

    一.程序.进程和线程   程序是一组指令的有序集合,也可以将其通俗地理解为若干行代码.它本身没有任何运行的含义,它只是一个静态的实体,它可能只是一个单纯的文本文件,也有可能是经过编译之后生成的可执行文 ...

  6. Java多线程编程(4)--线程同步机制

    一.锁 1.锁的概念   线程安全问题的产生是因为多个线程并发访问共享数据造成的,如果能将多个线程对共享数据的并发访问改为串行访问,即一个共享数据同一时刻只能被一个线程访问,就可以避免线程安全问题.锁 ...

  7. 《java多线程编程核心技术》不使用等待通知机制 实现线程间通信的 疑问分析

    不使用等待通知机制 实现线程间通信的 疑问分析 2018年04月03日 17:15:08       ayf 阅读数:33 编辑 <java多线程编程核心技术>一书第三章开头,有如下案例: ...

  8. Java多线程编程-线程之间的通信

    转载自:这里 学习了基础的线程知识 看到了 线程之间的通信 线程之间有哪些通信方式呢? 1.同步 这里讲的同步是指多个线程通过synchronized关键字这种方式来实现线程间的通信. public ...

  9. Java—多线程编程

    一个多线程程序包含两个或多个能并发运行的部分.程序的每一部分都称作一个线程,并且每个线程定义了一个独立的执行路径. 进程:一个进程包括由操作系统分配的内存空间,包含一个或多个线程.一个线程不能独立的存 ...

随机推荐

  1. 一、json与jsonp的使用

    1.json与jsonp的引入    在ajax中 JSON用来解决数据交换问题,而JSONP来实现跨域.    备注:跨域也可以通过服务器端代理来解决;    理解:JSON是一种数据交换格式,而J ...

  2. springMVC 的拦截器理解

    请复制以下链接看,我只是搬运工 http://blog.csdn.net/yerenyuan_pku/article/details/72567761 http://blog.csdn.net/u01 ...

  3. [].slice.call(k).filter(function(l) { return l != 0 });

    [].slice.call(k).filter(function(l) { return l != 0 }); 将类数组调用数组方法.

  4. N-tier architecture N层架构 (转)

    下面的内容既有我的理解,也有翻译的内容,翻译的书名为: <<Expert C# 2008 Business Objects >>http://www.douban.com/su ...

  5. 【转】十步让你成为一名优秀的Web开发人员

    第一步:学好HTML HTML(超文本标记语言)是网页的核心,因此你首先应该学好它,不要害怕,HTML很容易学习的,但也很容易误用,学懂容易要学精还得费点功夫,但学好HTML是成为Web开发人员的基本 ...

  6. 区间树Splay——[NOI2005]维护数列

    无指针Splay超详细讲解 区间树这玩意真TM玄学. 学这东西你必须要拥有的 1.通过[模板]文艺平衡树(Splay),[模板]普通平衡树,GSS3 - Can you answer these qu ...

  7. centOS+DJango+mysql_nginx部署流程记录

    安装Python3.6.2: https://www.jianshu.com/p/7a76bcc401a1 安装MySQL: https://www.cnblogs.com/luohanguo/p/9 ...

  8. 进程fork

    fork用于父进程创建一个子进程 返回两次 返回-1表示错误 父进程中返回创建子进程的ID,大于0 返回0是表示进入子进程 创建的子进程会继承父进程的属性,比如打开的文件描述符.工作目录.根目录等等. ...

  9. J.K.罗琳女士---《失败的好处和想象的重要性》

    目录 sohu ruanyifeng web sohu http://www.sohu.com/a/166181502_467718 <哈利波特>的作者J.K.罗琳女士在出席一次哈佛大学的 ...

  10. java 连接远程Linux 服务器

    创建闭锁,确保能连接到zk服务器. // 创建闭锁final CountDownLatch countDownLatch = new CountDownLatch(1); String connect ...