後臺線程是指在程序運行的時候在後臺提供一種通用服務的線程,並且這種線程並不屬於程序中不可或缺的一部分。因此,當所有的非後臺線程結束時,程序也就終止了,同時會殺死進程中的所有後臺線程。反過來說,只要有任何非後臺線程還在運行,程序就不會終止。比如,執行main()的就是一個非後臺線程。
import java.util.concurrent.TimeUnit;
public class SimpleDaemos implements Runnable {
@Override
public void run() {
try {
while(true){
/*對Thread.sleep方法的包裝,實現是一樣的,只是多了時間單位轉換和驗證,
然而TimeUnit枚舉成員的方法卻提供更好的可讀性*/
TimeUnit.MILLISECONDS.sleep(100);
System.out.println(Thread.currentThread() + " " + this);
}
} catch (Exception e) {
System.out.println("sleep() interrupted");
}
}
public static void main(String[] args) throws InterruptedException {
for(int i = 0;i < 10;i++){
Thread daemon = new Thread(new SimpleDaemos());
//設置當前線程爲後臺線程
daemon.setDaemon(true);
//線程初始化
daemon.start();
}
System.out.println("All daemons started");
TimeUnit.MILLISECONDS.sleep(150);
//TimeUnit.MILLISECONDS.sleep(200);
}
}
必須在線程啓動之前調用setDaemon()方法,才能把它設置爲後臺線程。
main()休眠150毫秒期間後臺線程運行的數量
main()休眠200毫秒期間後臺線程運行的數量
main()休眠150毫秒期間後臺線程運行的數量(關閉了線程的休眠時間)
由上面三張截圖可以發現main()這個非後臺線程沒有結束的時候,後臺線程一直在運行。
後臺線程創建的任何線程將被自動設置爲後臺線程
當你運行這個程序時,你將看到finally子句將不會執行,但是如果你註釋掉setDaemon(true)的調用,就會看到finally子句將會執行。
這種行爲是正確的,當最後一個非後臺線程終止是,後臺線程會“突然”終止。因此一旦main()退出,JVM就會立即關閉所有的後臺線程。