JVM的结束条件

思考一个问题:如果主函数开启了一个线程,那主函数运行结束,程序会继续运行吗?

实验代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
public class Main {
public static void main(String[] args) {
Runnable runnable = () -> {
System.out.println("子线程开始");
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("子线程结束");
};
Thread thread = new Thread(runnable);
thread.start();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("main end");
}
}

运行结果

程序输出为

  • 子线程开始
  • main end
  • 子线程结束

所以可以得出结论,主函数运行完成后,程序并没有退出,而是等待我们新开的线程运行完后才结束。
那么主函数运行完后主函数所在的线程还存在吗?在子线程里加上断点,可以看到main所在的线程已经消失了。但实验发现子线程的休眠时间如果设置的短一点,则main线程还在,推测是还没来得及销毁就被因为断点暂停了。

如果子线程是守护线程呢?

我们加上一句thread.setDaemon(true);

运行结果

  • 子线程开始
  • main end

可以看到JVM直接在main执行完后就退出了。查阅资料,JVM的退出条件是当前存活线程都为守护线程是退出,而main是一个特殊的非守护线程。