我有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" />
</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中运行代码时,终端始终处于活动状态)。即使执行程序线程完成了他们的工作,我的控制台也是这样的:
我认为这是因为,主线正在等待某事 - 有人告诉&#34;一切都已经完成,放松,去关闭&#34;
考虑这个解决方案 while(true)。你能告诉我这是不是好主意?可能它不好。
我知道这个执行者也有submit()方法。我想我不需要这里。如果我在这篇文章中不正确,请纠正我。
答案 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()
。这将阻止主线程执行。
之后,您可以安全地关闭线程池,知道所有工作都已完成。