如何关闭 ThreadPoolTask​​Executor?好办法

how to shutdown ThreadPoolTaskExecutor? Good way

我有 ThreadPoolTask​​Executor。我应该发送太多电子邮件(不同的电子邮件)。如果我在发送邮件时出错,我应该把它写到数据库中。

<bean id="taskExecutor"
    class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor">
    <property name="corePoolSize" value="5" />
    <property name="maxPoolSize" value="10" />
    <property name="WaitForTasksToCompleteOnShutdown" value="true" />
</bean>

我正在执行任务。 taskExecutor.execute(可运行)。一切正常!

@Override
public void run() {
    try {
        mailService.sendMail();
    } catch (Throwable t) {
        daoService.writeFaillStatus();
    }
} 

一切正常!异步请求做得很好!

我也有

  white(true) { 
    if(executor.getActiveCount()==0){
       executor.shutdown(); break;
     }
      Thread.sleep(3000)
    }

因为 WaitForTasksToCompleteOnShutdown=true 任务永远不会自动关闭。换句话说,主线程永远不会被销毁(主线程是我调用线程执行程序任务的线程 - 当我 运行 在 eclipse 中编写代码时,终端始终处于活动状态)。即使在执行程序线程完成工作后,我的控制台也如下所示:

我认为这是因为,主线程正在等待某些东西 - 有人告诉 "everything is already done, relax, go and shut down"

所以想到了这个解决方案while(true)。你能告诉我这是不是个好主意?可能是不太好吧。

我知道这个执行器也有 submit() 方法。我想我不需要这里。如果我在这方面不正确,请纠正我 post。

因为您使用的是 Spring ThreadPoolTaskExecutor,您很幸运。

如果您配置以下内容,它将允许您指定在强制关闭之前等待的秒数。

<bean id="taskExecutor"
     class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor">
    <property name="corePoolSize" value="5" />
    <property name="maxPoolSize" value="10" />
    <property name="WaitForTasksToCompleteOnShutdown" value="true" />
    <property name="awaitTerminationSeconds" value="X" />
</bean>

将 X 的值设置为您希望进程在终止前等待的秒数。

来自 awaitTerminationSeconds

的文档

If the "waitForTasksToCompleteOnShutdown" flag has been set to true, it will continue to fully execute all ongoing tasks as well as all remaining tasks in the queue, in parallel to the rest of the container shutting down. In either case, if you specify an await-termination period using this property, this executor will wait for the given time (max) for the termination of tasks. As a rule of thumb, specify a significantly higher timeout here if you set "waitForTasksToCompleteOnShutdown" to true at the same time, since all remaining tasks in the queue will still get executed - in contrast to the default shutdown behavior where it's just about waiting for currently executing tasks that aren't reacting to thread interruption.

基本上,您试图强行执行一些本应由框架单独处理的事情。由于特殊情况,应该由框架决定何时关闭任务执行器。我会删除所有试图关闭任务执行器的代码,并让 Spring 处理关闭,当你所有的工作都完成时。然后 Spring 也会正确关闭主电源。

如果您事先知道有多少 "too many emails",我建议您查看 CountDownLatch 而不是繁忙的等待循环来检查任务状态。

在主线程中设置

CountDownLatch latch =  new CountDownLatch(TOO_MANY_EMAILS);

将此实例传递给可运行实例,我们在发送每封邮件后调用latch.countDown()

在主线程中我们等待闩锁倒计时:latch.await()。这将阻止主线程执行。

之后您可以安全地关闭线程池,知道所有工作都已完成。