我有一个使用Quartz Scheduler的Java应用程序,它以SchedulerFactoryBean的形式出现。
问题在于Scheduler在其自己的线程中运行,因此当主线程完成提交作业时,它会返回并且Scheduler继续运行。当Scheduler最终完成(甚至如果您明确调用
我的两个解决方案:
有没有更好的方法,或者这些真的是我的唯一选择?
编辑:在回家的路上思考这个问题时,我得出结论,这可能是由于我正在使用SchedulerFactoryBean引起的。当Spring初始化应用程序上下文时,它会自动启动-这似乎将其放在主线程的范围之外。如果我选择稍微不同的调度程序,在代码中手动初始化并调用
编辑:这个...http://quartz-scheduler.org/documentation/quartz-2.x/examples/Example1 为了让程序有运行任务的机会,我们将休眠90秒钟。调度程序在后台运行,并应在这90秒钟内触发任务。 显然,这样做不起作用,因为调度程序似乎总是在后台运行。
main()
方法获取应用程序上下文,检索根bean,并开始调度作业。问题在于Scheduler在其自己的线程中运行,因此当主线程完成提交作业时,它会返回并且Scheduler继续运行。当Scheduler最终完成(甚至如果您明确调用
shutdown()
),应用程序仍然挂起。我的两个解决方案:
- 跟踪作业/触发器计数,每当向调度程序添加作业时增加它。将一个简单的SchedulerListener附加到调度程序上,每次调用
triggerFinalized()
时减小此计数,并设置一个while
循环,其中包含一个Thread.sleep()
,它不断检查计数是否达到0。当它达到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秒钟内触发任务。 显然,这样做不起作用,因为调度程序似乎总是在后台运行。
synchronized
块让我有些困惑。我知道它们看起来像简单的互斥锁,并且我也知道synchronized
关键字的工作原理(请一个线程一个线程地执行),但我不完全清楚这里正在同步什么。我猜这与主线程和调度器线程都持有exitLock对象有关? - Random Human