• 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
    
  • 相关阅读:
    正则匹配英文和数字
    python 正则匹配小数
    Error loading MySQLdb module: No module named 'MySQLdb'
    使用STL的next_permutation函数
    C++模板类之pair
    【转】Java迭代:Iterator和Iterable接口
    经典DFS问题实践
    Java 算法(背包,队列和栈)
    深度学习caffe测试代码c++
    opencv测试代码
  • 原文地址:https://www.cnblogs.com/zerodsLearnJava/p/12943896.html
Copyright © 2020-2023  润新知