main線程終止,其餘線程還會運行嗎?

這個問題也能夠換個說法,main線程是最後退出的線程嗎?java

理論分析

當你啓動一個Java Application的時候,這個時候系統建立一個進程,分配各項資源,而後這個進程啓動了Main線程.ide

咱們通常把Main線程說成主線程,由於其餘線程通常是由main線程啓動的.工具

但其實,在進程層面看起來,main其實也是一個普通的線程.只不過一些其餘的線程都是由main啓動的.idea

咱們能夠猜測一下:正常狀況下,main線程啓動了其餘線程,他們各自執行,彼此不受影響.spa

猜測依據:由於操做系統分配資源的單位是進程,就算main線程退出了,進程也還在.資源還在.在進程看來,線程應該都是平級的,沒有父子關係.操作系統

實踐驗證

咱們模擬一個線程池的例子,從main線程啓動一個線程池,當發生異常,則讓main線程拋出異常終止,看看線程池是否還繼續運行.線程

這裏因爲網上有些爭論認爲打印的方式沒法判斷main線程是否終止,因此咱們的示例使用異常終止,而且使用jconsole工具進行驗證.3d

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() + "異常");
            }
        }
    }
}		

複製代碼

咱們能夠在jconsole中觀察到:code

在main線程先出現而後會消失,線程池中的線程還在,只不過是wait狀態. 在idea中直接運行代碼,也能夠觀察到一樣的結論.cdn

總結

  • JVM會在全部的非守護線程(用戶線程)執行完畢後退出;
  • main線程是用戶線程;
  • 僅有main線程一個用戶線程執行完畢,不能決定JVM是否退出,也便是說main線程並不必定是最後一個退出的線程。

若是你但願在main線程退出後,全部其餘線程也退出.那麼你能夠把其餘線程都設置爲守護線程,也就是setDaemon(true). 對於線程池,你能夠在main線程退出的的時候手動進行一些處理.好比shutdown等方法.

相關文章
相關標籤/搜索