ExecutorService JVM不会终止

时间:2015-05-02 06:13:27

标签: java multithreading executorservice java.util.concurrent

  

我不明白为什么我要调用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会死。

1 个答案:

答案 0 :(得分:4)

根据Thread javadoc

  

Java虚拟机继续执行线程,直到发生以下任一情况:

     
      
  • 已调用类Runtime的exit方法,安全管理器已允许退出操作。
  •   
  • 所有非守护程序线程的线程已经死亡,可以是通过调用run方法返回,也可以抛出一个超出run方法传播的异常。
  •   

您的执行程序会创建非守护程序线程,以防止JVM关闭。执行程序创建的线程通常被池化以运行提交给执行程序的多个任务 - 通常这是重用线程的性能优化,因此它们运行多个任务(因为创建新线程是一项昂贵的操作)。根据执行程序的实现和配置(例如,参见ThreadPoolExecutor doc, especially keepalive configuration),它可能会使线程永久运行,或者在未使用一段时间后终止。

您必须在执行程序上调用shutdown或使用自定义ThreadFactory创建它(例如使用Executors.newFixedThreadPool(int, ThreadFactory)),其中该线程工厂将新线程配置为守护程序。