这个问题也能够换个说法,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
若是你但愿在main线程退出后,全部其余线程也退出.那么你能够把其余线程都设置为守护线程,也就是setDaemon(true). 对于线程池,你能够在main线程退出的的时候手动进行一些处理.好比shutdown等方法.