在Java中有两类线程用户线程(UserThread)守护线程(DaemonThread)
所谓守护线程是指在程序运行的时候在后台提供一种通用服务的线程比如垃圾回收线程就是一个很称职的守护者并且这种线程并不属于程序中不可或缺的部分因此当所有的非守护线程结束时程序也就终止了同时会杀死进程中的所有守护线程反过来说只要任何非守护线程还在运行程序就不会终止
用户线程和守护线程两者几乎没有区别唯一的不同之处就在于虚拟机的离开如果用户线程已经全部退出运行了只剩下守护线程存在了虚拟机也就退出了因为没有了被守护者守护线程也就没有工作可做了也就没有继续运行程序的必要了
将线程转换为守护线程可以通过调用Thread对象的setDaemon(true)方法来实现在使用守护线程时需要注意一下几点
()threadsetDaemon(true)必须在threadstart()之前设置否则会跑出一个IllegalThreadStateException异常你不能把正在运行的常规线程设置为守护线程
()在Daemon线程中产生的新线程也是Daemon的
()守护线程应该永远不去访问固有资源如文件数据库因为它会在任何时候甚至在一个操作的中间发生中断
代码示例
import ncurrentTimeUnit/** * 守护线程*/ public class Daemons { /** * @param args * @throws InterruptedException */ public static void main(String[] args) throws InterruptedException { Thread d = new Thread(new Daemon())dsetDaemon(true) //必须在启动线程前调用dstart()Systemoutprintln(disDaemon() = + disDaemon() + )TimeUnitSECONDSsleep()} class DaemonSpawn implements Runnable { public void run() { while (true) { Threadyield()} class Daemon implements Runnable { private Thread[] t = new Thread[]public void run() { for (int i= i<tlength i++) { t[i] = new Thread(new DaemonSpawn())t[i]start()Systemoutprintln(DaemonSpawn + i + started)} for (int i= i<tlength i++) { Systemoutprintln(t[ + i + ]isDaemon() = + t[i]isDaemon() + )} while (true) { Threadyield()}运行结果
disDaemon() = true DaemonSpawn started DaemonSpawn started DaemonSpawn started DaemonSpawn started DaemonSpawn started DaemonSpawn started DaemonSpawn started DaemonSpawn started DaemonSpawn started DaemonSpawn started t[]isDaemon() = true t[]isDaemon() = true t[]isDaemon() = true t[]isDaemon() = true t[]isDaemon() = true t[]isDaemon() = true t[]isDaemon() = true t[]isDaemon() = true t[]isDaemon() = true t[]isDaemon() = true
以上结果说明了守护线程中产生的新线程也是守护线程
如果将mian函数中的TimeUnitSECONDSsleep()注释掉运行结果如下
disDaemon() = true DaemonSpawn started DaemonSpawn started DaemonSpawn started DaemonSpawn started DaemonSpawn started DaemonSpawn started DaemonSpawn started DaemonSpawn started DaemonSpawn started DaemonSpawn started以上结果说明了如果用户线程已经全部退出运行了只剩下守护线程存在了虚拟机也就退出了下面的例子也说明了这个问题
代码示例
import ncurrentTimeUnit/** * Finally shoud be always run ?
*/ public class DaemonsDontRunFinally { /** * @param args */ public static void main(String[] args) { Thread t = new Thread(new ADaemon())tsetDaemon(true)tstart()} class ADaemon implements Runnable { public void run() { try { Systemoutprintln(start ADaemon……)TimeUnitSECONDSsleep()} catch (InterruptedException e) { Systemoutprintln(Exiting via InterruptedException)} finally { Systemoutprintln(This shoud be always run ?)}运行结果
start ADaemon……
如果将main函数中的tsetDaemon(true)注释掉运行结果如下
start ADaemon……
This shoud be always run ?