2016-02-26 61 views
0

我的計劃任務需要在部署在tomcat上的Web應用程序中運行。我使用Spring引導與Java 8Spring Scheduler線程無法在tomcat中關閉

我做什麼,

配置類

@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()); 
    } 
} 

JOB -1

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 
    } 
} 

JOB-2也相似

所有的工作正常,除了當我嘗試停止應用程序。 Tomcat日誌說,在我創建的10個線程中有7-8個線程存在內存泄漏。日誌:

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"Executor不起作用?

回答

0

如果我使用ExecutorService,請將線程關閉,並在ServletContextListener中調用shutdown()。例如:

@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()); 
    } 

} 

與聽者,

@Configuration 
public class CustomServletContextListener implements ServletContextListener { 

    @Autowired 
    private ExecutorService executorService; 

    @Override 
    public void contextInitialized(ServletContextEvent context) { 
    } 

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

} 

感謝。

+0

請參閱此問題以正確使用關機:http://stackoverflow.com/questions/36644043/how-to-forcefully-shutdown-java-executorservice/36644320#36644320 –