守护线程(Daemon Thread)

在Java中有两类线程:用户线程 (User Thread)、守护线程 (Daemon Thread)。 java

所谓守护 线程,是指在程序运行的时候在后台提供一种通用服务的线程,好比垃圾回收线程就是一个很称职的守护者,而且这种线程并不属于程序中不可或缺的部分。所以,当全部的非守护线程结束时,程序也就终止了,同时会杀死进程中的全部守护线程。反过来讲,只要任何非守护线程还在运行,程序就不会终止。数据库

用户线程和守护线程二者几乎没有区别,惟一的不一样之处就在于虚拟机的离开:若是用户线程已经所有退出运行了,只剩下守护线程存在了,虚拟机也就退出了。 由于没有了被守护者,守护线程也就没有工做可作了,也就没有继续运行程序的必要了。函数

将线程转换为守护线程能够经过调用Thread对象的setDaemon(true)方法来实现。在使用守护线程时须要注意一下几点:spa

 

(1) thread.setDaemon(true)必须在thread.start()以前设置,不然会跑出一个IllegalThreadStateException异常。你不能把正在运行的常规线程设置为守护线程。 线程

(2) 在Daemon线程中产生的新线程也是Daemon的。code

(3) 守护线程应该永远不去访问固有资源,如文件、数据库,由于它会在任什么时候候甚至在一个操做的中间发生中断。对象

代码示例:blog

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 ?

相关文章
相关标签/搜索