我有一个 Java 应用程序,它以 SchedulerFactoryBean 的名义使用 Quartz Scheduler。该main()
方法获取应用程序上下文,检索根 bean,并开始调度作业。
问题是调度程序在自己的线程中运行,因此当主线程完成提交作业时,它会返回并且调度程序在没有它的情况下继续运行。当调度器最终完成时(或者即使你明确地调用shutdown()
它),应用程序就会永远挂在那里。
我有两个解决方案:
- 跟踪作业/触发器计数,每当您将作业添加到调度程序时都会增加它。将一个简单的SchedulerListener附加到调度程序,每次调用都会减少此计数
triggerFinalized()
,并设置while
一个内部循环Thread.sleep()
,不断检查计数是否达到 0。当它达到时,它将返回到main()
方法和应用程序将正常退出。 - 从选项 1 中获取自定义 SchedulerListener,并跟踪其中的作业计数。每次调用增加,每次调用
jobAdded()
减少triggerFinalized()
。当计数达到 0 时,调用shutdown()
调度程序(或不调用,这实际上并不重要),然后调用System.exit(0)
.
我已经依次独立地实现了这两个,所以我知道它们实际上都在起作用。问题是它们都很糟糕。一个无限while
循环轮询一个值?System.exit(0)
? 布莱尔。
有人有更好的方法吗,或者这些真的是我唯一的选择吗?
编辑:在回家的路上思考这个问题时,我得出的结论是,这可能是由于我使用的是 SchedulerFactoryBean 造成的。当 Spring 初始化应用程序上下文时,它会自动启动 - 这似乎将其置于主线程范围之外。如果我使用手动初始化并start()
在代码中调用的稍微不同的调度程序,这是否会在主线程中运行调度程序,从而阻塞它直到调度程序完成运行所有作业?或者我还会有这个问题吗?
编辑:儿子... http://quartz-scheduler.org/documentation/quartz-2.x/examples/Example1
为了让程序有机会运行作业,我们然后休眠 90 秒。调度程序在后台运行,应该在这 90 秒内启动作业。
显然,这是行不通的,因为调度程序似乎总是在后台运行。