笔记:

  1. 第一篇转载写的比较好,将守护线程同linux的守护进程概念进行了对比。
  2. 当非守护线程执行完jvm就退出,不管是否还有守护线程在执行。所以守护线程尽量不要执行逻辑代码,顶多执行一些可有可无的辅助性代码。
  3. 什么东西作为守护线程,还是不太明确?第二篇举了一个实际例子,可以加深理解。

以下转载自:http://blog.csdn.net/basycia/article/details/51852583?locationNum=3&fps=1

Java守护线程:可以理解为后台管理者,服务线程!!!

应用道友的例子:

1.比如你正在 用 Java 写成的编辑器 写 Word 文档,你一边敲键盘,这是个 非守护线程, 后台还有一个 拼写检查 线程,它是个守护线程,他尽量不打扰你写稿子, 你们可以同时进行,他发现有拼写错误时在状态条显示错误,但是你可以忽略。

2.就像 城堡门前有个卫兵 (守护线程),里面有诸侯(非守护线程),他们是可以同时干着各自的活儿,但是 城堡里面的人都搬走了, 那么卫兵也就没有存在的意义了。

from:http://www.cnblogs.com/super-d2/p/3348183.html

估计学过Unix开发但是没有细致学习Java的同学们会疑惑了,操作系统里面是没有所谓的守护线程的概念,只有守护进程一说,但是Java语言机制是构建在JVM的基础之上的,意思是Java平台把操作系统的底层给屏蔽起来,所以它可以在它自己的虚拟的平台里面构造出对自己有利的机制,而语言或者说平台的设计者多多少少是收到Unix思想的影响,而守护线程机制又是对JVM这样的平台凑合,于是守护线程应运而生。

Daemon的作用是为其他线程的运行提供服务,比如说GC线程。其实User Thread线程和Daemon Thread守护线程本质上来说去没啥区别的,唯一的区别之处就在虚拟机的离开:如果User Thread全部撤离,那么Daemon Thread也就没啥线程好服务的了,所以虚拟机也就退出了。

守护线程并非虚拟机内部可以提供,用户也可以自行的设定守护线程,方法:public final void setDaemon(boolean on) ;但是有几点需要注意:

1)、thread.setDaemon(true)必须在thread.start()之前设置,否则会跑出一个IllegalThreadStateException异常。你不能把正在运行的常规线程设置为守护线程。  (备注:这点与守护进程有着明显的区别,守护进程是创建后,让进程摆脱原会话的控制+让进程摆脱原进程组的控制+让进程摆脱原控制终端的控制;所以说寄托于虚拟机的语言机制跟系统级语言有着本质上面的区别)

2)、 在Daemon线程中产生的新线程也是Daemon的。  (这一点又是有着本质的区别了:守护进程fork()出来的子进程不再是守护进程,尽管它把父进程的进程相关信息复制过去了,但是子进程的进程的父进程不是init进程,所谓的守护进程本质上说就是“父进程挂掉,init收养,然后文件0,1,2都是/dev/null,当前目录到/”)

3)、不是所有的应用都可以分配给Daemon线程来进行服务,比如读写操作或者计算逻辑。因为在Daemon Thread还没来的及进行操作时,虚拟机可能已经退出了。

[java]  view plain copy
  1. class ThreadDemo implements Runnable {
  2. public void run() {
  3. while (true) {
  4. for (int i = 1; i <= 10; i++) {
  5. System.out.println(i);
  6. try {
  7. Thread.sleep(1000);
  8. } catch (InterruptedException e) {
  9. e.printStackTrace();
  10. }
  11. }
  12. }
  13. }
  14. }
  15. public class Demo {
  16. public static void main(String[] args) {
  17. Thread daemonThread = new Thread(new ThreadDemo());
  18. daemonThread.setName("测试thread");
  19. // 设置为守护进程
  20. daemonThread.setDaemon(true);
  21. daemonThread.start();
  22. System.out.println("isDaemon = " + daemonThread.isDaemon());
  23. /*Thread t = new Thread(new ThreadDemo());
  24. t.start();*/
  25. }
  26. }
  27. /*因为有线程t 的存在,守护线程daemonThread 一直执行,当将下面代码注释掉时,守护线程daemonThread ,随着main结束,而结束。
  28. Thread t = new Thread(new ThreadDemo());
  29. t.start();*/

以下转载自:http://blog.csdn.net/SoulOfAndroid/article/details/41720999?locationNum=4&fps=1

补充说明:
定义:守护线程--也称“服务线程”,在没有用户线程可服务时会自动离开。
优先级:守护线程的优先级比较低,用于为系统中的其它对象和线程提供服务。
设置:通过setDaemon(true)来设置线程为“守护线程”;将一个用户线程设置为
守护线程的方式是在 线程对象创建 之前 用线程对象的setDaemon方法。
example: 垃圾回收线程就是一个经典的守护线程,当我们的程序中不再有任何运行的
Thread,程序就不会再产生垃圾,垃圾回收器也就无事可做,所以当垃圾回收线程是
JVM上仅剩的线程时,垃圾回收线程会自动离开。它始终在低级别的状态中运行,用于
实时监控和管理系统中的可回收资源。
生命周期:守护进程(Daemon)是运行在后台的一种特殊进程。它独立于控制终端并且
周期性地执行某种任务或等待处理某些发生的事件。也就是
说守护线程不依赖于终端,但是依赖于系统,与系统“同生共死”。那Java的守护线程是
什么样子的呢。当JVM中所有的线程都是守护线程的时候,JVM就可以退出了;如果还有一个
或以上的非守护线程则JVM不会退出。

实际应用例子:

在使用长连接的comet服务端推送技术中,消息推送线程设置为守护线程,服务于ChatServlet的servlet用户线程,在servlet的init启动消息线程,servlet一旦初始化后,一直存在服务器,servlet摧毁后,消息线程自动退出

容器收到一个Servlet请求,调度线程从线程池中选出一个工作者线程,将请求传递给该工作者线程,然后由该线程来执行Servlet的 service方法。当这个线程正在执行的时候,容器收到另外一个请求,调度线程同样从线程池中选出另一个工作者线程来服务新的请求,容器并不关心这个请求是否访问的是同一个Servlet.当容器同时收到对同一个Servlet的多个请求的时候,那么这个Servlet的service()方法将在多线程中并发执行。
Servlet容器默认采用单实例多线程的方式来处理请求,这样减少产生Servlet实例的开销,提升了对请求的响应时间,对于Tomcat可以在server.xml中通过<Connector>元素设置线程池中线程的数目。
如图:

 

为什么要用守护线程?

我们知道静态变量是ClassLoader级别的,如果Web应用程序停止,这些静态变量也会从JVM中清除。但是线程则是JVM级别的,如果你在Web 应用中启动一个线程,这个线程的生命周期并不会和Web应用程序保持同步。也就是说,即使你停止了Web应用,这个线程依旧是活跃的。正是因为这个很隐晦 的问题,所以很多有经验的开发者不太赞成在Web应用中私自启动线程。

如果我们手工使用JDK Timer(Quartz的Scheduler),在Web容器启动时启动Timer,当Web容器关闭时,除非你手工关闭这个Timer,否则Timer中的任务还会继续运行!

下面通过一个小例子来演示这个“诡异”的现象,我们通过ServletContextListener在Web容器启动时创建一个Timer并周期性地运行一个任务:

[java]  view plain copy
  1. //代码清单StartCycleRunTask:容器监听器
  2. package com.baobaotao.web;
  3. import java.util.Date;
  4. import java.util.Timer;
  5. import java.util.TimerTask;
  6. import javax.servlet.ServletContextEvent;
  7. import javax.servlet.ServletContextListener;
  8. public class StartCycleRunTask implements ServletContextListener ...{
  9. private Timer timer;
  10. public void contextDestroyed(ServletContextEvent arg0) ...{
  11. // ②该方法在Web容器关闭时执行
  12. System.out.println("Web应用程序启动关闭...");
  13. }
  14. public void contextInitialized(ServletContextEvent arg0) ...{
  15. //②在Web容器启动时自动执行该方法
  16. System.out.println("Web应用程序启动...");
  17. timer = new Timer();//②-1:创建一个Timer,Timer内部自动创建一个背景线程
  18. TimerTask task = new SimpleTimerTask();
  19. timer.schedule(task, 1000L, 5000L); //②-2:注册一个5秒钟运行一次的任务
  20. }
  21. }
  22. class SimpleTimerTask extends TimerTask ...{//③任务
  23. private int count;
  24. public void run() ...{
  25. System.out.println((++count)+"execute task..."+(new Date()));
  26. }
  27. }

在web.xml中声明这个Web容器监听器:<?xml version="1.0" encoding="UTF-8"?>
<web-app> 
… 
<listener> 
<listener-class>com.baobaotao.web.StartCycleRunTask</listener-class> 
</listener> 
</web-app>

在Tomcat中部署这个Web应用并启动后,你将看到任务每隔5秒钟执行一次。 
运行一段时间后,登录Tomcat管理后台,将对应的Web应用(chapter13)关闭。

转到Tomcat控制台,你将看到虽然Web应用已经关闭,但Timer任务还在我行我素地执行如故——舞台已经拆除,戏子继续表演:

我们可以通过改变清单StartCycleRunTask的代码,在contextDestroyed(ServletContextEvent arg0)中添加timer.cancel()代码,在Web容器关闭后手工停止Timer来结束任务。

Spring为JDK Timer和Quartz Scheduler所提供的TimerFactoryBean和SchedulerFactoryBean能够和Spring容器的生命周期关联,在 Spring容器启动时启动调度器,而在Spring容器关闭时,停止调度器。所以在Spring中通过这两个FactoryBean配置调度器,再从 Spring IoC中获取调度器引用进行任务调度将不会出现这种Web容器关闭而任务依然运行的问题。而如果你在程序中直接使用Timer或Scheduler,如不 进行额外的处理,将会出现这一问题。

JAVA守护线程 非守护线程相关推荐

  1. java多线程 --ConcurrentLinkedQueue 非阻塞 线程安全队列

    ConcurrentLinkedQueue是一个基于链接节点的无界线程安全队列,它采用先进先出的规则对节点进行排序,当我们添加一个元素的时候,它会添加到队列的尾部:当我们获取一个元素时,它会返回队列头 ...

  2. 多线程基础-守护线程与非守护线程

    守护线程与非守护线程 1.线程分类: 2.程序线程: 3.主线程与非守护线程 4.主线程与守护线程 5.主线程.守护线程.非守护线程 6. java虚拟机是如何退出的? 1.线程分类: 守护线程 非守 ...

  3. 并发编程之多线程基础-守护线程与非守护线程(四)

    守护线程概念: 只要当前JVM实例中尚存在任何一个非守护线程没有结束, 守护线程就全部工作; 只有当最后一个非守护线程结 束时, 守护线程随着 JVM 一同结束工作. 守护线程最典型的应用就是 GC ...

  4. linux daemon守护线程,线程8--守护线程Daemon

    packagebook.thread;/*** Daemon(守护)线程 * Daemon线程区别一般线程之处是: * 只有虚拟机中的用户线程(非Daimon线程)全部结束,Daemon线程就会立即结 ...

  5. java子线程切换到主线程_Android子线程切换到UI线程方法总结

    线程切换 通过消息发送(发布)和接收(订阅)的方式切换的. 1 .Handler 子线程(非UI线程)调用handler对象sendMessage(msg)方法,将消息发送给关联Looper,Loop ...

  6. 【C++ 语言】线程 ( 线程创建方法 | 线程标识符 | 线程属性 | 线程属性初始化 | 线程属性销毁 | 分离线程 | 线程调度策略 | 线程优先级 | 线程等待 )

    文章目录 I 线程创建方法 II 线程执行函数 III 线程标识符 IV 线程属性 V 线程属性 1 ( 分离线程 | 非分离线程 ) VI 线程属性 2 ( 线程调度策略 ) VII 线程属性 3 ...

  7. linux非守护线程一直不释放,Linux pthread 和 java thread 的是 / 非守护线程的行为

    Linux pthread 和 java thread 的是 / 非守护线程的行为 pthread_xxx 的函数并没有直接提供设置一个 pthread 为守护线程的 API 而 pthread_at ...

  8. Java中的守护线程和非守护线程(转载)

    <什么是守护线程,什么是非守护线程> Java有两种Thread:"守护线程Daemon"(守护线程)与"用户线程User"(非守护线程). 用户线 ...

  9. java守护线程与非守护线程

    java守护线程与非守护线程 代码逻辑 当前网上结论 1.主线程结束,守护线程跟着结束 2.只要存在任何一个非守护线程,守护线程就全部工作 测试代码 第一段代码 第二段代码 结论 代码逻辑 代码里面包 ...

最新文章

  1. python中的datatype啥意思_案例中使用的是dataType,但是用在联系上面dataType不可用,必须改写成type:..._慕课问答...
  2. 走近分形与混沌(part10)--用简单的规律来描述复杂的大自然
  3. 运行,JUnit! 跑!!!
  4. 操作系统 —— 文件管理
  5. Android学习之调用系统相机实现拍照功能
  6. JQuery的Ajax跨域请求的解决方案
  7. linux如何找大文件夹,Linux系统中如何查找大文件或目录文件夹的方法
  8. 思科命令敲错等待解决方案
  9. 华为手机克隆无法迁移联系人_华为手机克隆软件使用问题及解决办法
  10. atom n270 cpu linux,继续改造ATOM N270增加千兆口自制软路由
  11. 如何批量生成ISBN条码
  12. Unity3d接入googleplay内购详细说明(四)
  13. Android 多渠道包
  14. 2017年IT人期末考试卷,能考60分就是自己人!
  15. react项目中遇到的几个问题
  16. 如何防止表单重复提交(后端)
  17. 电子稳定程序系统--ESP
  18. 软件测试周度目标,部门周度工作计划表(新)-
  19. 阿里云天池超级码力在线编程大赛初赛 第2场 ABCD(A.计算几何 判断点在三角形内 D.大施罗德数/超级卡特兰数)
  20. 送一朵玫瑰花给女朋友

热门文章

  1. SEO重要的是初心不变
  2. (课堂作业)spring-boot集成shiro的步骤及代码解析
  3. 已更新或删除的行值要么不能使该行成为唯一行
  4. qq音乐——获取歌曲图片和名称
  5. Android 微信支付加密
  6. Python爬虫爬小说《诡秘之主》
  7. 分布式缓存之memcached以及LAMP的搭建
  8. 哪个相机可以拍gif动图_魅族手机如何拍摄Gif图片 魅族手机拍摄Gif动图的方法图解...
  9. 8086-逻辑运算指令
  10. 数据处理 过采样与欠采样 SMOTE与随机采样 达到样本均衡化