在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 ?
From:http://tw.wingwit.com/Article/program/Java/hx/201311/27133.html