java - 在主线程中等待 Quartz Scheduler 完成

标签 java quartz-scheduler

我有一个 Java 应用程序,它以 SchedulerFactoryBean 的形式使用 Quartz Scheduler。 . main() 方法获取应用程序上下文、检索根 bean 并开始调度作业。

问题是调度器在它自己的线程中运行,所以当主线程完成提交作业时,它返回并且调度器在没有它的情况下继续运行。当 Scheduler 最终完成时(或者即使您在其上显式调用 shutdown()),应用程序也会永远卡在那里。

我有两个解决方案:

  1. 跟踪作业/触发器计数,每当您向调度程序添加作业时增加它。附上一个简单的SchedulerListener到每次调用 triggerFinalized() 时递减此计数的调度程序,并设置一个 while 循环,其中包含 Thread.sleep()它不断检查计数是否已达到 0。当达到 0 时,它将返回到 main() 方法,应用程序将正常退出。
  2. 采用选项 1 中的自定义 SchedulerListener,并跟踪其中的作业计数。每次调用 jobAdded() 时递增,每次调用 triggerFinalized() 时递减。当计数为 0 时,在调度程序上调用 shutdown()(或不调用,实际上并不重要),然后调用 System.exit(0)。<

我已经依次独立实现了这两个,所以我知道它们都实际起作用。问题是他们都很糟糕。一个无限的 while 循环轮询一个值? System.exit(0)?布莱格。

有人有更好的方法吗,或者这些真的是我唯一的选择吗?

编辑: 在回家的路上思考这个问题,我得出的结论是,这可能是因为我正在使用 SchedulerFactoryBean。这在 Spring 初始化应用程序上下文时自动启动 - 这似乎将它放在主线程的范围之外。如果我使用一个稍微不同的调度程序,我手动初始化并在代码中调用 start() on,这是否会在主线程中运行调度程序,从而阻塞它直到调度程序完成所有作业的运行?或者我还会有这个问题吗?

编辑: ... http://quartz-scheduler.org/documentation/quartz-2.x/examples/Example1

To let the program have an opportunity to run the job, we then sleep for 90 seconds. The scheduler is running in the background and should fire off the job during those 90 seconds.

显然,这行不通,因为调度程序似乎总是在后台运行。

最佳答案

在您的 SchedulerListener 中添加一个专门用于同步和锁定的对象。将其称为 exitLock 或其他名称。您的主线程检索调度程序,设置监听器,提交所有作业,然后在返回之前执行

Object exitLock = listener.getExitLock();
synchronized (exitLock) {
    exitLock.wait(); // wait unless notified to terminate
}

在每次调用 triggerFinalized() 时,您的监听器都会减少挂起作业的计数器。一旦所有作业执行完毕,您的监听器就会关闭调度程序。

if (--pendingJobs == 0)
    scheduler.shutdown(); // notice, we don't notify exit from here

一旦调度程序关闭,它就会在监听器上调用最后一个回调,我们通知主线程终止,因此程序正常退出。

void schedulerShutdown() {
    // scheduler has stopped
    synchronized (exitLock) {
        exitLock.notify(); // notify the main thread to terminate
    }
}

我们没有在 triggerFinalized() 中通知所有待处理作业完成的原因是,万一调度程序过早关闭并且并非所有作业都完成,我们将离开我们的 main线程挂。通过通知响应关闭事件,我们确保我们的程序成功退出。

关于java - 在主线程中等待 Quartz Scheduler 完成,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16744865/

相关文章:

java - 如何对 Android 相机图像进行傅立叶变换?

java - 加特林机的替代品

jakarta-ee - kubernetes jee:“ map 资源”属性文件

java - wildfly-service.exe 因模块名称 : ntdll. dll 错误而崩溃

java - 在 selenium 测试中遇到 ng 选择框的问题

java - 通过 append 原始文件名来保存文件

java - 使用servlet提交时数据库中没有数据

java - 添加到触发器的 JobData 未传递给 Quartz 中的作业

mysql - 测试环境的 Quartz 调度程序不工作

Grails - 用于 Quartz 插件持久性的数据库迁移