转载自:http://www.cnblogs.com/luochengor/archive/2011/08/11/2134818.html

在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 ?

JAVA - 守护线程(Daemon Thread)的更多相关文章

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

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

  2. JAVA并发编程——守护线程(Daemon Thread)

    在Java中有两类线程:用户线程 (User Thread).守护线程 (Daemon Thread). 所谓守护 线程,是指在程序运行的时候在后台提供一种通用服务的线程,比如垃圾回收线程就是一个很称 ...

  3. 守护线程(Daemon Thread)

    在Java中有两类线程:用户线程 (User Thread).守护线程 (Daemon Thread). 所谓守护 线程,是指在程序运行的时候在后台提供一种通用服务的线程,比如垃圾回收线程就是一个很称 ...

  4. 用户线程 (User Thread)、守护线程 (Daemon Thread)

    在Java中有两类线程:用户线程 (User Thread).守护线程 (Daemon Thread). 所谓守护 线程,是指在程序运行的时候在后台提供一种通用服务的线程,比如垃圾回收线程就是一个很称 ...

  5. 白话JAVA守护线程

    OneCoder(苦逼Coder)原创,转载请务必注明出处: http://www.coderli.com/archives/daemon-thread-plain-words/ 关于“白话”:偶然想 ...

  6. [19/04/08-星期一] 多线程_线程的优先级(Priority) 和 守护线程(Daemon)

    一.概念 1. 处于就绪状态的线程,会进入“就绪队列”等待JVM来挑选. 2. 线程的优先级用数字表示,范围从1到10,一个线程的缺省优先级是5. 3. 使用下列方法获得或设置线程对象的优先级. in ...

  7. java 守护线程整理

    java中finally语句不走的可能存在system.exit(0)与守护线程 线程sleep采用TimeUnit类 设定线程的名字thread.getcurrentThread().setName ...

  8. java中的daemon thread

    java中的daemon thread java中有两种类型的thread,user threads 和 daemon threads. User threads是高优先级的thread,JVM将会等 ...

  9. 【多线程】守护线程 Daemon

    守护线程 Daemon 线程分为用户线程和守护线程 虚拟机必须确保用户线程执行完毕 虚拟机不用等待守护线程执行完毕 如,后台记录操作日志,监控内存,垃圾回收等待.. 代码示例: /** * @Desc ...

随机推荐

  1. LRY_FX_Assist(辅助EA)

    功能说明 辅助EA就是别的EA没有功能用这个EA来弥补,比如说风控设置(预付款.浮亏.加仓层数等达到多少进行操作),移动止损(包括隐藏移动止损),启动马丁加仓等.这个EA不能自己独立开单,只能辅助其它 ...

  2. TF随笔-13

    import tensorflow as tf a=tf.constant(5) b=tf.constant(3) res1=tf.divide(a,b) res2=tf.div(a,b) with ...

  3. 基于spec评论——王者荣耀交流协会的PSP DAILY作品

    一.运行环境 win10系统. Visual Studio 2017 二.运行程序及截图 1.进入界面如下图. 2.手动输入 类别 任务 点击开始,自动记录时间.如下图. 3.点击结束按钮,会有提示窗 ...

  4. UML图 之 活动图 (汇总版)

    ============================================================ 摘自: https://blog.csdn.net/tigaoban/arti ...

  5. batchsize的选择

    参考链接:http://www.zhihu.com/question/32673260 其中链接中提到,theano Python接口,支持RBM,DBN,MLP...等

  6. C# 图片生成缩略图

    C# 图片生成缩略图方法: /// <summary> /// 生成缩略图 /// </summary> /// <param name="fileName&q ...

  7. C语言使用pthread多线程编程(windows系统)一

    运行之前需要做一些配置: 1.下载PTHREAD的WINDOWS开发包 pthreads-w32-2-4-0-release.exe(任何一个版本均可)    http://sourceware.or ...

  8. nginx rewrite规则实例讲解

    一.正则表达式匹配,其中: * ~ 为区分大小写匹配* ~* 为不区分大小写匹配* !~和!~*分别为区分大小写不匹配及不区分大小写不匹配 二.文件及目录匹配,其中:* -f和!-f用来判断是否存在文 ...

  9. HBase,region以及HFile概念

    什么是HBase的Region? 大家一定对一个词不陌生:域分区,这个域就是Region:Region定义为key的一个取值范围的子集的数据载体:比如常见的域分区有固定大小分区,比如1-10一个reg ...

  10. Phonegap下localStorage使用实践

    HTML5的Web Storage API提供了两种客户端存储数据的方法 localStorage和sessionStorage. localStorage没有时间限制,程序升级也不会消失,可以满足持 ...