ExecutorService的shutdown到底什么时候关闭

Posted zerodslearnjava

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ExecutorService的shutdown到底什么时候关闭相关的知识,希望对你有一定的参考价值。

最近看了下Java线程池的源码,ExecutorService里面关于shutdown和shutdownNow的注释不太能理解啥意思。

直接翻译字面意思是,开启一个有序的关闭,先前提交的任务会被执行,但不接受新任务。如果已关闭,则调用不会产生任何其他影响。但是这个方法不会等待已提交任务完成执行。

这里可以有几个含义:

  • 肯定不接受新任务了
  • 已提交的任务是否会执行完呢
    • 会,但是不会等
    • 这里不会等的意思是线程池支持用户关闭线程池,但是用户没需要等待里面已提交的任务完成了才可以继续做别的事,可以用非阻塞调用去理解。调用后线程池isShutDown变为true,但是isTerminated要等到已提交任务都完成才会变成true

下面写了一段程序去验证了下

    /**
     * Initiates an orderly shutdown in which previously submitted
     * tasks are executed, but no new tasks will be accepted.
     * Invocation has no additional effect if already shut down.
     *
     * <p>This method does not wait for previously submitted tasks to
     * complete execution.  Use {@link #awaitTermination awaitTermination}
     * to do that.
    void shutdown();

public class ExecutorShutDownTest {
    public static final Integer TASK_NUM = 10;

    private static ExecutorService pool = new ThreadPoolExecutor(
            2, 4,
            2, TimeUnit.SECONDS,
            new ArrayBlockingQueue<>(10),
            new ShutDownThreadFactory(),
            new ThreadPoolExecutor.CallerRunsPolicy()
    );;

    public static void main(String[] args) throws InterruptedException, IOException {
        for (int i = 0; i < TASK_NUM; i++) {
            pool.execute(new ThreadTask(i));
        }

        System.out.println("Error happened, terminate executing tasks");
        pool.shutdown();
        if (pool.isShutdown()) {
            System.out.println("The ThreadPool is shutdown");
        }
        for (int i = TASK_NUM; i < TASK_NUM * 2; i++) {
            pool.execute(new ThreadTask(i));
        }

        System.out.println("Main ends");

        while (!pool.isTerminated()) {

        }

        System.out.println("exit");
    }
}
	
class ThreadTask implements Runnable {
    private Integer taskNum;

    public ThreadTask(Integer taskNum) {
        this.taskNum = taskNum;
    }

    @Override
    public void run() {
        System.out.println(Thread.currentThread().getName() + " start to execute Task " + taskNum + " =====>");
        try {
            TimeUnit.SECONDS.sleep(5);
            System.out.println("^_^  Task + " + taskNum + " done!");
        } catch (InterruptedException e) {
            System.out.println("┭┮﹏┭┮ Task" + taskNum + " interrupt unexpectedly");
        }
    }
}

class ShutDownThreadFactory implements ThreadFactory {
    private AtomicInteger threadNum = new AtomicInteger();

    @Override
    public Thread newThread(Runnable r) {
        threadNum.incrementAndGet();
        return new Thread(r,"Thread" + threadNum.get());
    }
}

下面是执行的结果,可以对比下上面的解释理解下

Thread1 start to execute Task 0 =====>
Thread2 start to execute Task 1 =====>
Error happened, terminate executing tasks
The ThreadPool is shutdown
Main ends
^_^  Task + 0 done!
^_^  Task + 1 done!
Thread1 start to execute Task 2 =====>
Thread2 start to execute Task 3 =====>
^_^  Task + 3 done!
^_^  Task + 2 done!
Thread2 start to execute Task 4 =====>
Thread1 start to execute Task 5 =====>
^_^  Task + 4 done!
^_^  Task + 5 done!
Thread2 start to execute Task 6 =====>
Thread1 start to execute Task 7 =====>
^_^  Task + 6 done!
^_^  Task + 7 done!
Thread2 start to execute Task 8 =====>
Thread1 start to execute Task 9 =====>
^_^  Task + 8 done!
^_^  Task + 9 done!
exit

以上是关于ExecutorService的shutdown到底什么时候关闭的主要内容,如果未能解决你的问题,请参考以下文章

在 ExecutorService 上调用 shutdown() 的原因

ExecutorService对象的shutdown 和shutdownNow 的区别

ExecutorService的shutdown到底什么时候关闭

ExecutorService 中 shutdown()shutdownNow()awaitTermination() 含义和区别

ExecutorService接口概要

ExecutorService和ThreadPoolExecutor运行原理