所谓“后台”(daemon)线程,是指程序运行的时候,在后台提供一种通用服务的线程,并
且这种服务并不属于程序中不可或缺的部分。因此,当所有的非后台线程结束,程序也就
终止了。反过来说,只要有任何非后台线程还在运行,程序就不会终止。比如,执行main( )
的就是一个非后台线程。
//: c13:SimpleDaemons.java
// Daemon threads don't prevent the programfrom
ending.
public class SimpleDaemons extends Thread {
public SimpleDaemons() {
setDaemon(true); // Must be called before start()
start();
}
public void run() {
while(true){
try{
sleep(100);
}catch(InterruptedException e) {
throw newRuntimeException(e);
}
System.out.println(this);
}
}
public static void main(String[] args) {
for(inti = 0; i < 10; i++)
newSimpleDaemons();
}
}
你必须在线程启动之前调用 setDaemon()方法,才能把它设置为后台线程。在 run( )
里面,线程被设定为休眠一段时间。一旦所有的线程都启动了,程序马上会在所有的线程
能打印信息之前立刻终止,这是因为没有非后台线程(除了 main( ))使得程序保持运行。
因此,程序未打印任何信息就终止了。
你可以通过调用isDaemon()方法来确定线程是否是一个后台线程。如果是一个后台线程,
那么它创建的任何线程将被自动设置成后台线程,如下例所示:
//: c13:Daemons.java
// Daemon threads spawn other daemonthreads.
import java.io.*;
import com.bruceeckel.simpletest.*;
class Daemon extends Thread {
private Thread[] t = newThread[10];
public Daemon() {
setDaemon(true);
start();
}
public void run() {
for(inti = 0; i < t.length; i++)
t[i] = newDaemonSpawn(i);
for(inti = 0; i < t.length; i++)
System.out.println("t[" + i + "].isDaemon() =
"
+ t[i].isDaemon());
while(true)
yield();
}
}
class DaemonSpawn extends Thread {
public DaemonSpawn(int i) {
start();
System.out.println("DaemonSpawn " + i + "
started");
}
public void run() {
while(true)
yield();
}
}
public class Daemons {
private static Test monitor = new Test();
public static void main(String[] args) throws
Exception {
Thread d = newDaemon();
System.out.println("d.isDaemon()= " +
d.isDaemon());
// Allow the daemon threads to
// finish their startup processes:
Thread.sleep(1000);
monitor.expect(new String[] {
"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"
},Test.IGNORE_ORDER + Test.WAIT);
}
} ///:~
在 Daemon 线程中把后台标志设置为“真”,然后派生出许多子线程,这些线程并没有被明
确设置是否为后台线程,不过它们的确是后台线程。接着,线程进入了无限循环,并在循
环里调用yield( )方法来把控制权交给其它进程。
一旦main( )完成其工作,就没什么能阻止程序终止了,因为除了后台线程之外,已经没
有线程在运行了。main( )线程被设定为睡眠一段时间,所以你可以观察到所有后台线程
启动后的结果。不这样的话,你就只能看见一些后台线程创建时得到的结果。(试试调整
sleep( )休眠的时间,以观察这个行为。)