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

时间:2015-03-12 20:46:16

标签: 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>

我正在执行任务。 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中运行代码时,终端始终处于活动状态)。即使执行程序线程完成了他们的工作,我的控制台也是这样的:enter image description here

我认为这是因为,主线正在等待某事 - 有人告诉&#34;一切都已经完成,放松,去关闭&#34;

考虑这个解决方案 while(true)。你能告诉我这是不是好主意?可能它不好。

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

2 个答案:

答案 0 :(得分: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>

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

来自awaitTerminationSeconds

的文档
  

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

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

答案 1 :(得分:2)

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

在主线程中设置

CountDownLatch latch =  new CountDownLatch(TOO_MANY_EMAILS);

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

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

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