Tomcat 6中的Quartz调度器,线程不停止

13

我使用Quartz作为Web应用程序。当我部署应用程序时一切正常,但是当我卸载该应用程序时,Quartz线程没有被销毁。

日志显示:

INFO: 停止服务Catalina

SEVERE: web应用[/example]似乎已经启动了一个名为[DefaultQuartzScheduler_Worker-1]的线程,但未能停止它。这很可能会导致内存泄漏。 Jul 12, 2010 6:30:40 PM org.apache.catalina.loader.WebappClassLoader clearReferencesThreads

有人能告诉我如何强制销毁这些线程吗?

谢谢,

Tommaso

3个回答

7
我发现我的问题在于quartz被关闭,但Web应用程序在关闭之前没有等待quartz完成,因此Tomcat认为它留下了运行中的线程并抱怨。
所以我像这样管理我的调度程序:
Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler();
...do some stuff with the scheduler...
scheduler.shutdown(true);

请注意,传递给关闭方法的布尔参数是至关重要的部分。如果您将其设置为false,或者调用没有参数的版本,则您的Web应用程序将在关闭之前不会等待Quartz停止。

简而言之:调用scheduler.shutdown(true)使您的Web应用程序等待Quartz完成。


4

你是如何启动Quartz的?

假设你没有使用像Spring这样方便的包装器,你可能想在你的应用程序的web.xml中使用<listener>,以便Quartz可以被通知应用程序的启动和关闭。

请参见QuartzInitializerListenerQuartzInitializerServlet等示例。


1
我通过org.springframework.scheduling.quartz.SchedulerFactoryBean将控制权交给Spring的Quartz。<bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean" destroy-method="destroy"> <property name="triggers"> <list> <ref bean="cronTrigger"/> </list> </property> <property name="quartzProperties"> <props> <prop key="org.quartz.threadPool.class">org.quartz.simpl.SimpleThreadPool</prop> ... </props> </property> </bean> - Tommaso Taruffi
你是如何初始化/启动Spring的呢?是通过ContextLoaderListener吗?当应用程序关闭时,Spring是否会收到通知? - matt b
是的,可以通过ContextLoaderListener启动Spring,并且Spring会在应用程序关闭时收到通知。 - Tommaso Taruffi
1
SchedulerFactoryBeandestroy() 方法将使用 waitForJobsToCompleteOnShutdown 布尔参数调用 org.quartz.Scheduler.shutdown()。你是否在 SchedulerFactoryBean 中将此标志设置为 true?也许 Tomcat 在关闭之前没有足够长的时间等待 Quartz 中的作业完成。 - matt b
该参数已设置为true,但等待2分钟后Tomcat仍未停止。 - Tommaso Taruffi
显示剩余3条评论

0

我建议您使用2.x版本,并在web.xml中添加监听器。

将以下方法添加到监听器中:

public void contextDestroyed(ServletContextEvent event) {

    if (this.contextLoader != null && event!=null && event
        .getServletContext()!=null) {
        ServletContext context = event.getServletContext();
        StdSchedulerFactory sch = (StdSchedulerFactory) context.getAttribute("org.quartz.impl.StdSchedulerFactory.KEY");

        if(sch!=null){
            try {
                logger.debug("call quartz Scheduler.shutdown()");
                Collection<Scheduler> col = sch.getAllSchedulers();
                for(Scheduler s:col){ 
                    s.shutdown();
                }
            } catch (SchedulerException e) {
                e.printStackTrace();
            }
        }
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接