这个问题已经在这里有了答案: > Java ServiceExecutor terminating condition 4个
I don’t understand why I have to call executorService.shutdown()
explicitly to terminate 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());
}
}
输出:
Message from Task2 :pool-1-thread-2
Message from Task1 :pool-1-thread-1
Message from Task3 :pool-1-thread-3
JVM仍然存在.如果我要调用shutdown(),那么只有JVM会死.
解决方法:
The Java Virtual Machine continues to execute threads until either of the following occurs:
- The exit method of class Runtime has been called and the security manager has permitted the exit operation to take place.
- All threads that are not daemon threads have died, either by returning from the call to the run method or by throwing an exception that propagates beyond the run method.
您的执行程序创建了非守护线程,以防止您的JVM关闭.执行者创建的线程通常被合并以运行提交给执行者的多个任务-通常,这是对性能的优化以重用线程,因此它们执行的任务多于一个任务(因为创建新线程是一项昂贵的操作).取决于执行程序的实现和配置(例如,参见ThreadPoolExecutor
doc, especially keepalive
configuration),它可能会使线程永远运行或在闲置一段时间后终止.
您必须在执行程序上调用shutdown或使用自定义ThreadFactory
(例如,使用Executors.newFixedThreadPool(int, ThreadFactory)
)创建该程序,其中该线程工厂将新线程配置为守护程序线程.