JAVA线程池如何优雅关闭

JAVA线程池如何优雅关闭

	Effective JAVA 第三版并发部分提起了线程池优雅关闭的问题,意识到之前的线程关闭知识还不完善。讨论如下:

1.shutdown()

  • 基本意思是:启动有序关闭,其中先前提交的任务将被执行关闭,但不会接受任何新任务。
    如果已经关闭,调用没有额外的作用。
    此方法不等待以前提交的任务完成执行。 使用awaitTermination做到这一点。
  • shutdown只负责任务关闭,不负责任务是否执行完毕。比如有线程往数据库写数据,当线程池任务shutdown时,数据未完全写入数据库。此时就会造成预期与实际的数据不一致。
  • 源码
    	
        /**
         * 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.
         *
         * @throws SecurityException {@inheritDoc}
         */
        private final ReentrantLock mainLock = new ReentrantLock();
        public void shutdown() {
            final ReentrantLock mainLock = this.mainLock;
            mainLock.lock();
            try {
                checkShutdownAccess();
                advanceRunState(SHUTDOWN);
                interruptIdleWorkers();
                onShutdown(); // hook for ScheduledThreadPoolExecutor
            } finally {
                mainLock.unlock();
            }
            tryTerminate();
        }
    
    

2.awaitTermination(long timeout, TimeUnit unit)

  • 基本意思是:在执行shutdown 或shutdownNow后,线程任务执行并未完全终止,如果任务执行完毕返回true,否则返回false 。
  • 说白了就是一个线程活动监测器,等所有任务执行完毕,优雅关闭。
  • 源码
       /**
         * Returns true if this executor is in the process of terminating
         * after {@link #shutdown} or {@link #shutdownNow} but has not
         * completely terminated.  This method may be useful for
         * debugging. A return of {@code true} reported a sufficient
         * period after shutdown may indicate that submitted tasks have
         * ignored or suppressed interruption, causing this executor not
         * to properly terminate.
         *
         * @return {@code true} if terminating but not yet terminated
         */
    public boolean awaitTermination(long timeout, TimeUnit unit)
            throws InterruptedException {
            long nanos = unit.toNanos(timeout);
            final ReentrantLock mainLock = this.mainLock;
            mainLock.lock();
            try {
                for (;;) {
                    if (runStateAtLeast(ctl.get(), TERMINATED))
                        return true;
                    if (nanos <= 0)
                        return false;
                    nanos = termination.awaitNanos(nanos);
                }
            } finally {
                mainLock.unlock();
            }
        }
    

3.优雅关闭

  • 使用

    pool.shutdown();
    while(!pool.awaitTermination(100, TimeUnit.MILLISECONDS)) {
    	 System.out.println("线程池尚未关闭!");
    }
    
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值