首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >tomcat中未关闭的Spring调度器线程

tomcat中未关闭的Spring调度器线程
EN

Stack Overflow用户
提问于 2016-02-26 11:42:44
回答 1查看 3.5K关注 0票数 2

我已经安排了需要在部署在tomcat上的Web应用程序中运行的任务。我在Java 8中使用Spring。

我所做的,

配置类

代码语言:javascript
复制
@Configuration
@EnableScheduling
class SchedulerConfiguration implements SchedulingConfigurer {

    @ConditionalOnProperty(name = "ScheduleJob1Switch", havingValue = "on")
    @Bean
    FirstScheduledJob firstScheduledJob() {
        return new FirstScheduledJob();
    }

    @ConditionalOnProperty(name = "ScheduleJob2Switch", havingValue = "on")
    @Bean
    SecondScheduledJob secondScheduledJob() {
        return new SecondScheduledJob();
    }

    @Bean(destroyMethod = "shutdown")
    Executor taskExecutors() {
        return Executors.newScheduledThreadPool(10);
    }

    @Override
    public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
        taskRegistrar.setScheduler(taskExecutors());
    }
}

作业-1

代码语言:javascript
复制
    public class FirstScheduledJob {

    private static final String CLASS_NAME = FirstScheduledJob.class.getName();

    @Autowired
    private SubHandlerDAO subHandlerDAO;

    @Autowired
    private LookupService lookupService;

    @Scheduled(cron = "${FirstScheduledJobCron}", zone = "UTC")
    void firstJob() throws Exception {
       //Do things
    }
}

作业-2也是类似的

所有操作都很好,除非我试图停止应用程序。Tomcat日志显示,在我创建的10个线程中,有7-8个线程存在内存泄漏。日志:

代码语言:javascript
复制
 26-Feb-2016 17:02:04.074 WARNING [localhost-startStop-2] org.apache.catalina.loader.WebappClassLoaderBase.clearReferencesThreads The web application [sample-job-handler-1.0.0] appears to have started a thread named [pool-1-thread-2] but has failed to stop it. This is very likely to create a memory leak. Stack trace of thread:
 sun.misc.Unsafe.park(Native Method)
 java.util.concurrent.locks.LockSupport.park(Unknown Source)
 java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(Unknown Source)
 java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(Unknown Source)
 java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(Unknown Source)
 java.util.concurrent.ThreadPoolExecutor.getTask(Unknown Source)
 java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
 java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
 java.lang.Thread.run(Unknown Source)

这是一个线程的日志。其他人也有同样的例外。为什么destroyMethod="shutdown" on Executor不能工作?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2016-05-19 06:09:46

如果我使用ExecutorService并在ServletContextListener中调用它的shutdown(),那么线程就可以很好地关闭。例如:

代码语言:javascript
复制
@Configuration
@EnableScheduling
public class SchedulerConfig implements SchedulingConfigurer {

    /* ............ */

    @Bean(name = "executorService")
    ExecutorService taskExecutors() {
        return Executors.newScheduledThreadPool(10);
    }

    @Override
    public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
        taskRegistrar.setScheduler(taskExecutors());
    }

}

而听众,

代码语言:javascript
复制
@Configuration
public class CustomServletContextListener implements ServletContextListener {

    @Autowired
    private ExecutorService executorService;

    @Override
    public void contextInitialized(ServletContextEvent context) {
    }

    @Override
    public void contextDestroyed(ServletContextEvent context) {
        executorService.shutdown();
    }

}

谢谢。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/35650809

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档