我正在开发一个 Spring Boot 应用程序,该应用程序接受请求并使用ExecutorService
处理它们。提交给ExecutorService
的每个任务都是非迭代的、长时间运行的且不可中断的(实质上,它通过消息传递代理依次将请求提交给其他几个服务,为每个服务提供块,并等待回复)。
我正在尝试实现应用程序的正常关闭,以便应用程序等待指定的时间让ExecutorService
完成所有正在运行的任务,然后关闭。如果在指定的时间过后,有未完成的任务,我希望应用程序记录任务的 ID。
相关代码为:
@Service
public class Service {
private ExecutorService es = Executors.newFixedThreadPool(10);
public handle(MyTask task) {
es.execute(task);
}
@PreDestroy
void destroy() {
es.shutdown();
try {
boolean terminated = es.awaitTermination(60, TimeUnit.SECONDS);
if (!terminated) {
// I want to somehow log the IDs of MyTask's that haven't finished processing
es.shutdownNow();
} catch (InterruptedException e) {
// Should not get here in the existing implementation as MyTask's are non-
// interruptible
}
}
我如何实现这一点?我正在考虑两个选项,但无法理解如何实现其中任何一个。
- 将
MyTask
包装到另一个Runnable
中,该将检查循环中的中断,如果中断,则记录MyTask
的 id。所以本质上使MyTask
可中断。如何实现这一点? - 将提交的
MyTask
保存在集合中,并在关闭时轮询集合以查找尚未完成的集合并记录其 ID。这里的问题是,如何使集合保持最新并删除已完成的MyTask
?
重申一下,我正在实现整个应用程序的正常关闭,而不仅仅是执行器服务。因此,整个应用程序将在指定的时间段过后关闭。因此,需要记录执行程序服务尚未完成处理的所有任务。
我想我可能已经根据这篇文章找到了一个选项:实现一个执行器服务,将任务放入地图中,并在完成处理后将其删除。关闭后,我们迭代映射并记录仍然存在的任务。其中一些可能会在日志记录和关闭应用之间完成,但误报是可以接受的。