java ExecutorService JVM不会终止

sd2nnvve  于 2023-04-28  发布在  Java
关注(0)|答案(1)|浏览(148)

我不明白为什么要显式调用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());

    }

}

输出:
来自Task 2的消息:pool-1-thread-2
来自Task 1的消息:pool-1-thread-1
来自Task 3的消息:pool-1-thread-3
JVM还活着。如果我调用shutdown(),那么只有JVM会死。

brgchamk

brgchamk1#

根据Thread javadoc
Java虚拟机将继续执行线程,直到出现以下任一情况:

  • 类Runtime的exit方法已被调用,并且安全管理器已允许执行exit操作。
    *所有不是守护线程的线程都已死亡,要么是从run方法的调用返回,要么是抛出一个传播到run方法之外的异常。

您的执行程序创建了非守护进程线程,以防止JVM关闭。执行器创建的线程通常被集中起来运行多个提交给执行器的任务-通常这是一种性能优化,以重用线程,使它们运行多个任务(因为创建新线程是一个昂贵的操作)。根据执行器的实现和配置(e.例如,参见ThreadPoolExecutor doc, especially keepalive configuration),它可能会使线程永远运行,或者在一段时间内未使用时终止。
您必须在executor上调用shutdown,或者使用自定义ThreadFactory创建它。例如使用Executors.newFixedThreadPool(int, ThreadFactory)),其中线程工厂将新线程配置为守护进程线程。

相关问题