我不明白为什么我要调用executorService.shutdown() 显式终止executorService。
如果我不调用shutdown(),则JVM不会自行终止。
我的计划有什么问题或我缺少什么概念?
public class ExecutorServiceExample {
public static class Task1 implements Runnable {
@Override
public void run() {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Message from Task1 :"
+ Thread.currentThread().getName());
}
}
public static class Task2 implements Runnable {
@Override
public void run() {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Message from Task2 :"
+ Thread.currentThread().getName());
}
}
public static class Task3 implements Runnable {
@Override
public void run() {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Message from Task3 :"
+ Thread.currentThread().getName());
}
}
public static void main(String[] args) {
ExecutorService executorService = Executors.newFixedThreadPool(10);
Future future1 = executorService.submit(new Task1());
Future future2 = executorService.submit(new Task2());
Future future3 = executorService.submit(new Task3());
}
}
输出:
来自Task2的消息:pool-1-thread-2
来自Task1的消息:pool-1-thread-1
来自Task3的消息:pool-1-thread-3
JVM还活着。如果我将调用shutdown(),那么只有JVM会死。
答案 0 :(得分:4)
Java虚拟机继续执行线程,直到发生以下任一情况:
- 已调用类Runtime的exit方法,安全管理器已允许退出操作。
- 所有非守护程序线程的线程已经死亡,可以是通过调用run方法返回,也可以抛出一个超出run方法传播的异常。
您的执行程序会创建非守护程序线程,以防止JVM关闭。执行程序创建的线程通常被池化以运行提交给执行程序的多个任务 - 通常这是重用线程的性能优化,因此它们运行多个任务(因为创建新线程是一项昂贵的操作)。根据执行程序的实现和配置(例如,参见ThreadPoolExecutor
doc, especially keepalive
configuration),它可能会使线程永久运行,或者在未使用一段时间后终止。
您必须在执行程序上调用shutdown
或使用自定义ThreadFactory
创建它(例如使用Executors.newFixedThreadPool(int, ThreadFactory)
),其中该线程工厂将新线程配置为守护程序。