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等方法.

相关文章
相关标签/搜索