“Daemon”線程的作用是在程序的運行期間於後台提供一種“常規”服務,但它並不屬於程序的一個基本部分。因此,一旦所有非Daemon線程完成,程序也會中止運行。相反,假若有任何非Daemon線程仍在運行(比如還有一個正在運行main()的線程),則程序的運行不會中止。
通過調用isDaemon(),可調查一個線程是不是一個Daemon,而且能用setDaemon()打開或者關閉一個線程的Daemon狀態。如果是一個Daemon線程,那麼它創建的任何線程也會自動具備Daemon屬性。
下面這個例子演示了Daemon線程的用法:
//: Daemons.java // Daemonic behavior import java.io.*; class Daemon extends Thread { private static final int SIZE = 10; private Thread[] t = new Thread[SIZE]; public Daemon() { setDaemon(true); start(); } public void run() { for(int i = 0; i < SIZE; i++) t[i] = new DaemonSpawn(i); for(int i = 0; i < SIZE; i++) System.out.println( "t[" + i + "].isDaemon() = " + t[i].isDaemon()); while(true) yield(); } } class DaemonSpawn extends Thread { public DaemonSpawn(int i) { System.out.println( "DaemonSpawn " + i + " started"); start(); } public void run() { while(true) yield(); } } public class Daemons { public static void main(String[] args) { Thread d = new Daemon(); System.out.println( "d.isDaemon() = " + d.isDaemon()); // Allow the daemon threads to finish // their startup processes: BufferedReader stdin = new BufferedReader( new InputStreamReader(System.in)); System.out.println("Waiting for CR"); try { stdin.readLine(); } catch(IOException e) {} } } ///:~
Daemon線程可將自己的Daemon標記設置成“真”,然後產生一系列其他線程,而且認為它們也具有Daemon屬性。隨後,它進入一個無限循環,在其中調用yield(),放棄對其他進程的控制。在這個程序早期的一個版本中,無限循環會使int計數器增值,但會使整個程序都好象陷入停頓狀態。換用yield()後,卻可使程序充滿“活力”,不會使人產生停滯或反應遲鈍的感覺。
一旦main()完成自己的工作,便沒有什麼能阻止程序中斷運行,因為這裡運行的只有Daemon線程。所以能看到啟動所有Daemon線程後顯示出來的結果,System.in也進行了相應的設置,使程序中斷前能等待一個回車。如果不進行這樣的設置,就只能看到創建Daemon線程的一部分結果(試試將readLine()代碼換成不同長度的sleep()調用,看看會有什麼表現)。