守护线程(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 ...
随机推荐
- rtthread移植到jz2440之BootLoader
从2016年第一次接触rtthread,感觉很容易上手,记得一个项目是小飞行器上的IPC,趁着空闲,手里有一块jz2440的板子,准备在这块板子上跑起来rtthread,查了很多资料,最后决定自己写一 ...
- R语言学习笔记(十九):字符串处理中预定义字符组(表格介绍)
R中预定义的字符组 代码 含义说明 [:digit:]或\\d 数字; [0-9] [^[:digit:]]或\\D 非数字; 等价于[^0-9] [:lower:] 小写字母; [a-z] [:up ...
- Java基础——注释规范
一.注释格式分类: 1.单行(single-line)注释://…… 2.块(block)注释:/*……*/ 3.文档注释:/**……*/ javadoc有如下: 二.加注释的场景: 1. 基本注释( ...
- 2017-2018-1 20155338 加分项目——PWD的实现
2017-2018-1 20155338 加分项目--PWD的实现 项目要求 1 学习pwd命令 2 研究pwd实现需要的系统调用(man -k; grep),写出伪代码 3 实现mypwd 4 测试 ...
- PosgreSQL 9.0 High Performance中文版瑕疵
磨砺技术珠矶,践行数据之道,追求卓越价值 回到上一级页面: PostgreSQL杂记页 回到顶级页面:PostgreSQL索引页 发表此文不是为了吐槽,而是为了防止更多的受害者出现啊,拿到书后 ...
- python基础学习1-三元表达式和lambda表达式
#!/usr/bin/env python # -*- coding:utf-8 -*- 三元运算 if else 的简写 name ="alex" if 1==1 else &q ...
- 排序算法:快速排序解析及Python实现
关键词:分而治之.递归.计算速度.基准值 1. 什么是分而治之? 1.1 分而治之(divide and conquer)一种递归式方法 1.2 找出基线条件,这种条件必须尽可能简单 1.3 不断将问 ...
- spring整合ehcache注解实现查询缓存,并实现实时缓存更新或删除
转载: http://www.importnew.com/23358.html 写在前面:上一篇博客写了spring cache和ehcache的基本介绍,个人建议先把这些最基本的知识了解了才能对今天 ...
- 【ASP.NET Core】运行原理(1):创建WebHost
本系列将分析ASP.NET Core运行原理 [ASP.NET Core]运行原理[1]:创建WebHost [ASP.NET Core]运行原理[2]:启动WebHost [ASP.NET Core ...
- Qt-网易云音乐界面实现-5 收藏列表,播放列表实现 QListWidget QTableWidget
先上目前完成的内容吧,发现后面越写越多.在看看点击量,心凉凉. 完成了左侧的导航列表,还有就是右下角的播放列表. //创建的歌单 my_Create_Music_List = new QListWid ...