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

gre*_*rep 2 spring spring-integration spring-io

我有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>
Run Code Online (Sandbox Code Playgroud)

我正在执行任务.taskExecutor.execute(可运行).一切都很好!

@Override
public void run() {
    try {
        mailService.sendMail();
    } catch (Throwable t) {
        daoService.writeFaillStatus();
    }
} 
Run Code Online (Sandbox Code Playgroud)

一切似乎都好!异步请求运行良好!

我也有

  white(true) { 
    if(executor.getActiveCount()==0){
       executor.shutdown(); break;
     }
      Thread.sleep(3000)
    }
Run Code Online (Sandbox Code Playgroud)

由于WaitForTasksToCompleteOnShutdown = true,任务永远不会自动关闭.换句话说,主线程永远不会被销毁(主线程是我调用线程执行器任务的线程 - 当我在eclipse中运行代码时,终端始终处于活动状态).即使执行程序线程完成他们的工作后我的控制台看起来像这样:在此输入图像描述

我认为这是因为,主要线程正在等待 - 有人告诉"一切都已经完成,放松,去关闭"

所以考虑这个解决方案(真实).你能告诉我这是不是好主意?可能它不好.

我知道这个执行器也有submit()方法.我想我不需要这里.请纠正我如果我在这篇文章中不正确.

Jam*_*ENL 8

因为你正在使用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>
Run Code Online (Sandbox Code Playgroud)

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

从文档中 awaitTerminationSeconds

如果"waitForTasksToCompleteOnShutdown"标志已设置为true,它将继续完全执行所有正在进行的任务以及队列中的所有剩余任务,与容器的其余部分并行关闭.在任何一种情况下,如果使用此属性指定等待终止时间段,则此执行程序将等待给定时间(最大)以终止任务.根据经验,如果同时将"waitForTasksToCompleteOnShutdown"设置为true,则在此处指定明显更高的超时,因为队列中的所有剩余任务仍将执行 - 与默认关闭行为相反,它只是在等待当前正在执行对线程中断没有反应的任务.

基本上,你正在努力做一些应该由框架单独处理的事情.由于特殊情况,它应该是决定何时关闭任务执行程序的框架.我将删除所有试图关闭任务执行程序的代码,并让Spring处理关闭,当你的所有工作都完成时.然后Spring也将正确关闭主体.


Roh*_*hit 3

如果您事先知道有多少是“电子邮件太多”,我建议您查看CountDownLatch而不是繁忙的等待循环来检查任务状态。

在主线程中设置

CountDownLatch latch =  new CountDownLatch(TOO_MANY_EMAILS);
Run Code Online (Sandbox Code Playgroud)

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

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

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