当Tomcat关闭时,在Spring Boot中关闭Executor服务

时间:2019-02-15 20:55:41

标签: java spring spring-boot executorservice shutdown

我已经在Spring Boot中配置了执行程序服务,如下所示:

@Configuration
@PropertySource({ "classpath:executor.properties" })
public class ExecutorServiceConfig {

    @Value("${"executor.thread.count"}")
    private int executorThreadCount;

    @Bean("executorThreadPool")
    public ThreadPoolExecutor cachedThreadPool() {
        return new ThreadPoolExecutor(executorThreadCount, executorThreadCount, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>());
    }
}

该应用程序部署在独立的Tomcat实例上。当Tomcat服务器关闭时,我发现队列中仍有一些未完成的任务。结果,我将丢失数据。有没有办法让我在此执行程序服务上调用awaitTermination,以便它有机会完成队列中的内容?谢谢!

2 个答案:

答案 0 :(得分:2)

您可以通过配置TomcatEmbeddedServletContainerFactory bean来进入Tomcat生命周期。它具有addContextLifecycleListeners方法,该方法可让您实例化自己的LifecycleListener并根据需要处理任何Tomcat Lifecycle Events(例如,通过在awaitTermination上调用ExecutorService)。

@Configuration
public class TomcatConfiguration implements LifecycleListener {

    @Autowire("executorThreadPool")
    private ThreadPoolExecutor executor;

    @Bean
    public EmbeddedServletContainerFactory embeddedTomcatFactory() {
        TomcatEmbeddedServletContainerFactory factory = new TomcatEmbeddedServletContainerFactory();
        factory.addContextLifecycleListeners(this);
        return factory;
    }

    @Override
    public void lifecycleEvent(LifeCycleEvent event) {
        //if check for correct event        
        executor.awaitTermination();
    }
}

答案 1 :(得分:1)

使用@PreDestroy注释进行注释。然后从那里关闭执行服务。

@Configuration
class ExecutorServiceConfiguration {

    @Value("${"executor.thread.count"}")
    private int executorThreadCount;


     public static class MyExecutorService {
           private ThreadPoolExecutor executor;

           public MyExecutorService(ThreadPoolExecutor executor) {
               this.executor = executor;
           }
           @PreDestroy()
           public destroy() {
                  // destroy executor
           }
     }

    @Bean("executorThreadPool")
    public ThreadPoolExecutor cachedThreadPool() {
        return new ThreadPoolExecutor(executorThreadCount, executorThreadCount, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>());
    }

    @Bean
    public MyExecutorService configureDestroyableBean(ThreadPoolExecutor cachedThreadPool) 
    {
      return new MyExecutorService(cachedThreadPool);
    }

}