/**
* Shut down the Quartz scheduler on bean factory shutdown,
* stopping all scheduled jobs.
*/
public void destroy() throws SchedulerException {
logger.info("Shutting down Quartz Scheduler");
this.scheduler.shutdown(this.waitForJobsToCompleteOnShutdown);
}
表示工厂已经做了shutdown。所以,问题出现在真正执行的scheduler.shutdown(true)。
原来这是Quartz的bug(见https://jira.terracotta.org/jira/browse/QTZ-192),在调用scheduler.shutdown(true)后,Quartz检查线程并没有等待那些worker线程被停止就结束了。
网上说在Quartz2.1版本已经修补了这个bug,但笔者使用的2.2.1版本仍旧有问题。
问题的解决
那么问题如何解决,这里有一个不太美观的方案:在调用scheduler.shutdown(true)后,增加一点睡眠时间,等待worker线程全部停止。如下:
1。自定义schedulerFactory继承Spring的SchedulerFactoryBean,覆盖destroy()增加延时。
public class SchedulerFactoryBeanWithShutdownDelay extends SchedulerFactoryBean {
/**
* 关于Quartz内存泄漏的不太美观的解决方案:
* 在调用scheduler.shutdown(true)后增加延时,等待worker线程结束。
*/
@Override
public void destroy() throws SchedulerException {
super.destroy();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
}
2。把spring配置文件中的SchedulerFactoryBean替换为自定义的工厂即可。
<bean>
</bean>
OK,问题解决。