“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()調用,看看會有什麼表現)。