守护线程(Daemon Thread)
在Java中有两类线程:用户线程 (User Thread)、守护线程 (Daemon Thread)。
所谓守护 线程,是指在程序运行的时候在后台提供一种通用服务的线程,比如垃圾回收线程就是一个很称职的守护者,并且这种线程并不属于程序中不可或缺的部分。因此,当所有的非守护线程结束时,程序也就终止了,同时会杀死进程中的所有守护线程。反过来说,只要任何非守护线程还在运行,程序就不会终止。
用户线程和守护线程两者几乎没有区别,唯一的不同之处就在于虚拟机的离开:如果用户线程已经全部退出运行了,只剩下守护线程存在了,虚拟机也就退出了。 因为没有了被守护者,守护线程也就没有工作可做了,也就没有继续运行程序的必要了。
将线程转换为守护线程可以通过调用Thread对象的setDaemon(true)方法来实现。在使用守护线程时需要注意一下几点:
(1) thread.setDaemon(true)必须在thread.start()之前设置,否则会跑出一个IllegalThreadStateException异常。你不能把正在运行的常规线程设置为守护线程。
(2) 在Daemon线程中产生的新线程也是Daemon的。
(3) 守护线程应该永远不去访问固有资源,如文件、数据库,因为它会在任何时候甚至在一个操作的中间发生中断。
代码示例:
import java.util.concurrent.TimeUnit; /** * 守护线程 */ public class Daemons { /** * @param args * @throws InterruptedException */ public static void main(String[] args) throws InterruptedException { Thread d = new Thread(new Daemon()); d.setDaemon(true); //必须在启动线程前调用 d.start(); System.out.println("d.isDaemon() = " + d.isDaemon() + "."); TimeUnit.SECONDS.sleep(1); } } class DaemonSpawn implements Runnable { public void run() { while (true) { Thread.yield(); } } } class Daemon implements Runnable { private Thread[] t = new Thread[10]; public void run() { for (int i=0; i<t.length; i++) { t[i] = new Thread(new DaemonSpawn()); t[i].start(); System.out.println("DaemonSpawn " + i + " started."); } for (int i=0; i<t.length; i++) { System.out.println("t[" + i + "].isDaemon() = " + t[i].isDaemon() + "."); } while (true) { Thread.yield(); } } }
运行结果:
d.isDaemon() = true.
DaemonSpawn 0 started.
DaemonSpawn 1 started.
DaemonSpawn 2 started.
DaemonSpawn 3 started.
DaemonSpawn 4 started.
DaemonSpawn 5 started.
DaemonSpawn 6 started.
DaemonSpawn 7 started.
DaemonSpawn 8 started.
DaemonSpawn 9 started.
t[0].isDaemon() = true.
t[1].isDaemon() = true.
t[2].isDaemon() = true.
t[3].isDaemon() = true.
t[4].isDaemon() = true.
t[5].isDaemon() = true.
t[6].isDaemon() = true.
t[7].isDaemon() = true.
t[8].isDaemon() = true.
t[9].isDaemon() = true.
以上结果说明了守护线程中产生的新线程也是守护线程。
如果将mian函数中的TimeUnit.SECONDS.sleep(1);注释掉,运行结果如下:
d.isDaemon() = true.
DaemonSpawn 0 started.
DaemonSpawn 1 started.
DaemonSpawn 2 started.
DaemonSpawn 3 started.
DaemonSpawn 4 started.
DaemonSpawn 5 started.
DaemonSpawn 6 started.
DaemonSpawn 7 started.
DaemonSpawn 8 started.
DaemonSpawn 9 started.
以上结果说明了如果用户线程已经全部退出运行了,只剩下守护线程存在了,虚拟机也就退出了。下面的例子也说明了这个问题。
代码示例:
import java.util.concurrent.TimeUnit; /** * Finally shoud be always run ? */ public class DaemonsDontRunFinally { /** * @param args */ public static void main(String[] args) { Thread t = new Thread(new ADaemon()); t.setDaemon(true); t.start(); } } class ADaemon implements Runnable { public void run() { try { System.out.println("start ADaemon..."); TimeUnit.SECONDS.sleep(1); } catch (InterruptedException e) { System.out.println("Exiting via InterruptedException"); } finally { System.out.println("This shoud be always run ?"); } } }
运行结果:
start ADaemon...
如果将main函数中的t.setDaemon(true);注释掉,运行结果如下:
start ADaemon...
This shoud be always run ?
守护线程(Daemon Thread)的更多相关文章
- java并发编程学习: 守护线程(Daemon Thread)
在正式理解这个概念前,先把 守护线程 与 守护进程 这二个极其相似的说法区分开,守护进程通常是为了防止某些应用因各种意外原因退出,而在后台独立运行的系统服务或应用程序. 比如:我们开发了一个邮件发送程 ...
- JAVA并发编程——守护线程(Daemon Thread)
在Java中有两类线程:用户线程 (User Thread).守护线程 (Daemon Thread). 所谓守护 线程,是指在程序运行的时候在后台提供一种通用服务的线程,比如垃圾回收线程就是一个很称 ...
- JAVA - 守护线程(Daemon Thread)
转载自:http://www.cnblogs.com/luochengor/archive/2011/08/11/2134818.html 在Java中有两类线程:用户线程 (User Thread) ...
- 用户线程 (User Thread)、守护线程 (Daemon Thread)
在Java中有两类线程:用户线程 (User Thread).守护线程 (Daemon Thread). 所谓守护 线程,是指在程序运行的时候在后台提供一种通用服务的线程,比如垃圾回收线程就是一个很称 ...
- [19/04/08-星期一] 多线程_线程的优先级(Priority) 和 守护线程(Daemon)
一.概念 1. 处于就绪状态的线程,会进入“就绪队列”等待JVM来挑选. 2. 线程的优先级用数字表示,范围从1到10,一个线程的缺省优先级是5. 3. 使用下列方法获得或设置线程对象的优先级. in ...
- 【多线程】守护线程 Daemon
守护线程 Daemon 线程分为用户线程和守护线程 虚拟机必须确保用户线程执行完毕 虚拟机不用等待守护线程执行完毕 如,后台记录操作日志,监控内存,垃圾回收等待.. 代码示例: /** * @Desc ...
- 守护线程daemon
如下代码: from threading import Thread import time def func1(n): time.sleep(10) print(n) t = Thread(targ ...
- Java中的守护线程——daemon
絮叨 Java中有两类线程:User Thread(用户线程).Daemon Thread(守护线程) 定义:守护线程(aka:服务线程),在没有用户线程可服务时会自动离开. 优先级:守护线程的优先级 ...
- (14)线程- Event事件和守护线程Daemon
<一>Event事件 线程Event基本和进程的Event语法是一样的 # wait() 动态给程序加阻塞 # set() 将内部属性改成True # clear() 将内部属性改成Fal ...
随机推荐
- 关于Matlab在绘图时中文字体显示不一致的问题
我的运行环境: OS: Win10 教育版 64-bit Matlab版本:Matlab 2017a 64-bit 在使用Matlab绘图时,而横坐标轴.纵坐标轴.标题有汉字时,会发现在GUI的显示 ...
- RMAN中建立Catalog 用数据库的例子
RMAN中可以备份metadata到control文件,也可以备份metadata到数据库中,此数据库称为catalog database. 本文参考网上文章,建立一个例子: 使用机器: 机器1:ta ...
- cmp(x,y)
cmp(x,y) 函数用于比较2个对象,如果 x < y 返回 -1, 如果 x == y 返回 0, 如果 x > y 返回 1.
- set方法在set传入值时报空指针异常,直接设置定值即可
这种情况可能跟上下的程序有关,所以直接设置定值传入即可. 例如: re.setRid(ar.getRid()); // 这个是报错代码 md.setConnMailStatusTrue(ar.getR ...
- 无监控不运维——使用 Python 写一个小小的项目监控
在公司里做的一个接口系统,主要是对接第三方的系统接口,所以,这个系统里会和很多其他公司的项目交互.随之而来一个很蛋疼的问题,这么多公司的接口,不同公司接口的稳定性差别很大,访问量大的时候,有的不怎么行 ...
- jquery选择器:获取父级元素、同级元素、子元素
jQuery的出现给广大开发者提供了不少的方便.从要自己一个一个敲代码,到直接调用方法,无疑大大地提高了网站开发的效率.而在jQuery中有一些方法非常的实用.下面就给大家介绍下jquery选择器:获 ...
- nodejs 不支持 typescript (...paramName:any[])剩余参数。变相支持方式。
node es6 变相实现支持ts的剩余参数实现方式 //.ts method assign(to: any, options?: AssignOptions, ...forms: any[]){} ...
- JMeter转制LoadRunner HTTP协议脚本的小技巧
对于Http协议的请求,除了手工编写脚本外,JMeter还提供了录制浏览器操作的功能,甚是方便.那如果手头有一堆HTTP协议的LoadRunner脚本,能不能比较快速的转制成JMeter脚本呢?其实也 ...
- Linux(centos7)之更换安装python3(二)
Linux不比window好安装python,折腾了好久,终于成功安装上了python,window上一个安装包完事,可惜Linux上python版本太低不好使,还要更换为3版本,百度了好久,教程上总 ...
- dubbo 多人开发时(即开发环境),版本号不要一致
导致问题:如果版本号相同,会调到别人的服务 不需要修改配置文件.直接改idea配置即可. Configurations ====> 添加parameters ===> dubbo.cons ...