main線程終止,其他線程還會運行嗎?
其實,這個問題也可以換個說法:main線程是最後退出的線程嗎?
01 理論分析
當你啟動一個Java Application的時候,這個時候系統創建一個進程,分配各項資源,然後這個進程啟動了Main線程.
我們一般把Main線程說成主線程,因為其他線程一般是由main線程啟動的.但其實,在進程層面看起來,main其實也是一個普通的線程.只不過一些其他的線程都是由main啟動的.
我們可以猜想一下:正常情況下,main線程啟動了其他線程,他們各自執行,彼此不受影響.猜想依據:因為操作系統分配資源的單位是進程,就算main線程退出了,進程也還在.資源還在.在進程看來,線程應該都是平級的,沒有父子關係.這個問題也可以換個說法,main線程是最後退出的線程嗎?02 實踐驗證
我們模擬一個線程池的例子,從main線程啟動一個線程池,當發生異常,則讓main線程拋出異常終止,看看線程池是否還繼續運行.
這裡由於網上有些爭論認為列印的方式無法判斷main線程是否終止,所以我們的示例使用異常終止,並且使用jconsole工具進行驗證.public class ThreadPoolException {
ExecutorService threadPool = Executors.newFixedThreadPool(5);
public static void main(String[] args) {
ThreadPoolException t = new ThreadPoolException();
t.futureGet();
}
void futureGet() {
for (int i = 0; i < 5; i++) {
Future future = threadPool.submit(() -> {
System.out.println("current thread name" + Thread.currentThread().getName());
Object object = null;
System.out.print("result## " + object.toString());
});
try {
future.get();
} catch (Exception e) {
System.out.println(Thread.currentThread().getName() + "異常");
// 讓主線程多等一段時間,便於觀察.
try {
Thread.sleep(10000);
} catch (InterruptedException e1) {
e1.printStackTrace();
}
//主線程終止
throw new RuntimeException(Thread.currentThread().getName() + "異常");
}
}
}
}
歡迎大家關注我,需要更多Java面試資料和學習乾貨可以關注我的專欄【Tom貓的Java屋】
Tom貓的java屋
我們可以在jconsole中觀察到: