在tomcat7+quartz1.8/1.7 + spring3.0.5做定时任务的时候 , 当关闭tomcat时会发现如下异常:
- ar 27, 2013 6:05:35 PM org.apache.coyote.AbstractProtocol pause
- INFO: Pausing ProtocolHandler ["http-nio-8082"]
- Mar 27, 2013 6:05:35 PM org.apache.catalina.core.StandardService stopInternal
- INFO: Stopping service Catalina
- Mar 27, 2013 6:05:35 PM org.apache.catalina.loader.WebappClassLoader clearReferencesThreads
- SEVERE: The web application [/****] appears to have started a thread named [startQuertz_Worker-1] buthas failed to stop it. This is very likely to create a memory leak.
- Mar 27, 2013 6:05:35 PM org.apache.catalina.loader.WebappClassLoader clearReferencesThreads
- SEVERE: The web application [/****] appears to have started a thread named [startQuertz_Worker-2] buthas failed to stop it. This is very likely to create a memory leak.
- Mar 27, 2013 6:05:35 PM org.apache.catalina.loader.WebappClassLoader clearReferencesThreads
- SEVERE: The web application [/****] appears to have started a thread named [startQuertz_Worker-3] buthas failed to stop it. This is very likely to create a memory leak.
- Mar 27, 2013 6:05:35 PM org.apache.catalina.loader.WebappClassLoader clearReferencesThreads
首先怀疑线程泄漏 , 依各位前辈的经验建议 , 修改quartz的配置:
- <bean id="startQuertz" lazy-init="false" autowire="no"
- class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
- <property name="triggers">
- <list>
- </list>
- </property>
- <property name="quartzProperties">
- <props>
- <prop key="org.quartz.scheduler.instanceName">buy_it_now</prop>
- <prop key="org.quartz.threadPool.threadCount">2</prop>
- <prop key="org.quartz.plugin.shutdownhook.class">org.quartz.plugins.management.ShutdownHookPlugin</prop>
- <prop key="org.quartz.plugin.shutdownhook.cleanShutdown">true</prop>
- <prop key="org.quartz.threadPool.threadsInheritContextClassLoaderOfInitializingThread">true</prop>
- </props>
- </property>
日志warn可能线程泄漏 ,但事实并非如此(本人没考证) , 只是tomcat在shutdown做清理工作的时候没能等待quartz完成cleanShutdown !就是tomcat太心急了 , 说 “quartz , 我关门了 , 你走吧!” , 还没等quartz反应过来,
就要关大门 , 这时发现 “quartz , 你怎么还在这儿呀!”。 解决的办法简单:自己实现一个ServletContextListener ,
在contextDestroyed的时候主动调用quartz schedular的shutdown方法 ,并且主线程sleep一会儿 , 上例子:
- public class QuartzContextListener implements ServletContextListener {
- /*
- * 测试代码写得随便
- *
- * @seejavax.servlet.ServletContextListener#contextDestroyed(javax.servlet.
- * ServletContextEvent)
- */
- @Override
- public void contextDestroyed(ServletContextEvent arg0) {
- WebApplicationContext webApplicationContext = (WebApplicationContext) arg0
- .getServletContext()
- .getAttribute(
- WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE);
- org.quartz.impl.StdScheduler startQuertz = (org.quartz.impl.StdScheduler) webApplicationContext
- .getBean("startQuertz");
- if(startQuertz != null) {
- startQuertz.shutdown();
- }
- try {
- Thread.sleep(1000);
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- }
- /*
- * (non-Javadoc)
- *
- * @see
- * javax.servlet.ServletContextListener#contextInitialized(javax.servlet
- * .ServletContextEvent)
- */
- @Override
- public void contextInitialized(ServletContextEvent arg0) {
- <span style="white-space:pre"> </span>//不做任何事情
- }
- }
别忘了web.xml中添加起! 结束