1. 实例化一个调度器

(1)实例化一个默认的调度器

默认的调度器定义在quartz.properties文件中,该文件在当前工作目录下、classpath路径下,或者保存在quartz.jar中的后被默认值

  1. SchedulerFactory sf = new StdSchedulerFactory();
  2. Scheduler scheduler = sf.getScheduler();
  3. // 调度器直到被启动时才会执行作业 (尽管它们可以在启动前被调度)
  4. scheduler.start();

(2)从具体的属性中实例化一个具体的调度器

  1. StdSchedulerFactory sf = new StdSchedulerFactory();
  2. sf.initialize(schedulerProperties);
  3. Scheduler scheduler = sf.getScheduler();
  4. // 调度器知道被启动时才会执行作业 (尽管它们可以在启动前被调度)
  5. scheduler.start();

(3)从具体的配置文件中实例化一个调度器

  1. StdSchedulerFactory sf = new StdSchedulerFactory();
  2. sf.initialize(fileName);
  3. Scheduler scheduler = sf.getScheduler();
  4. // 调度器知道被启动时才会执行作业 (尽管它们可以在启动前被调度)
  5. scheduler.start();

2. 将调度器至于待机模式

  1. // start() 方法之前已经在调度器上被调用
  2. scheduler.standby();
  3. // 现在,调度程序将不会触发触发器/执行作业
  4. // ...
  5. scheduler.start();
  6. // 现在,调度程序将会触发触发器和执行作业

3. 终止一个调度器

终止或销毁一个调度器,只需要简单的调用shutdown()方法的其中一个
一旦你已经终止了一个调度器,它便不能再被重新启动(就像线程和其他资源被永久性的摧毁),如果你只是想简单的暂停一个调度器一段时间,请参照延缓方法。

(1)等待作业执行结束

  1. //shutdown() 直到作业完全执行完才会返回
  2. scheduler.shutdown(true);

(2)不等待作业执行结束

  1. //shutdown() 立即返回, 但执行的作业立即运行到结束
  2. scheduler.shutdown();
  3. //或者将值置为false
  4. scheduler.shutdown(false);

如果你在你的servlet容器中使用org.quartz.ee.servlet.QuartzInitializerListener 来启动调度器,那么当你的应用程序没被部署或者应用服务器关闭时,它的contextDestory()方法将会关闭调度器。(除非它的”shutdown-on-ubload”属性被显示地设置为false)

4. 在Servlet容器中初始化调度程序

下面展示了实现这一操作的两种途径。
在这两个例子中,一定要查阅相关类的JavaDoc来了解所有可能的参数,因为完整的参数集合下面的示例中未给出。

(1)在web.xml中添加一个Context/Contain监听器

  1. ...
  2. <context-param>
  3. <param-name>quartz:config-file</param-name>
  4. <param-value>/some/path/my_quartz.properties</param-value>
  5. </context-param>
  6. <context-param>
  7. <param-name>quartz:shutdown-on-unload</param-name>
  8. <param-value>true</param-value>
  9. </context-param>
  10. <context-param>
  11. <param-name>quartz:wait-on-shutdown</param-name>
  12. <param-value>false</param-value>
  13. </context-param>
  14. <context-param>
  15. <param-name>quartz:start-scheduler-on-load</param-name>
  16. <param-value>true</param-value>
  17. </context-param>
  18. ...
  19. <listener>
  20. <listener-class>
  21. org.quartz.ee.servlet.QuartzInitializerListener
  22. </listener-class>
  23. </listener>
  24. ...

(2)在web.xml中添加一个Start-up Servlet

  1. ...
  2. <servlet>
  3. <servlet-name>QuartzInitializer</servlet-name>
  4. <servlet-class>org.quartz.ee.servlet.QuartzInitializerServlet</servlet-class>
  5. <init-param>
  6. <param-name>shutdown-on-unload</param-name>
  7. <param-value>true</param-value>
  8. </init-param>
  9. <load-on-startup>2</load-on-startup>
  10. </servlet>
  11. ...

5. 使用多个(非集群)调度程序

你想要这么做的原因:

  • 为了管理多个资源——例如,你有个轻型和重型混合的job,你希望有这样一个调度器:许多线程服务轻型job,一个或几个线程服务重型job,为了防止你的机器资源被并发运行许多重型job而过载。
  • 在一个应用程序中调度job,但在另一个应用程序中执行它们(当使用IDBC-JobStore)

注意:你可以在任一个应用中创建你想要数量的scheduler,但是它们的scheduler name必须唯一(通常定义在quartz.properties文件中),这意味着你将需要编写多个属性文件,同样也需要你在初始StdSchedulerFactory的时候指定它们。(因为它默认只读取”quartz.properties”)

如果你运行多个调度器,他们当然有不同的特征——例如,一个可能使用RAMJobStore并且有100个worker线程,另一个可能使用JDBC-JobStore并且有20个worker线程

千万不要启动一个非集群实例使用具有相同调度器名称的任何其他实例所运行的同一组数据表,可能会出现严重的数据损坏,并且肯定会经历不稳定的行为。

关于在一个应用中调度Jobs而在另一个应用执行的示例/讨论

此描述/用法适用于JDBC-JobStore。你可能还希望查看适用于其他JobStore的,如RMI或JMX特性来控制远程进程中的调度程序。

现在,如果你需要一个运行在一个具体scheduler中的Job,那么这个scheduler必须是一个确切的(不同的)。

假设你有一个应用程序”APP A”需要调度jobs(基于用户输入),这个应用程序将需要在本地进程/机器”MachineA”(一些简单的jobs)或一个远程机器”MachineB”上运行(一些复杂的jobs)。可能在一个应用程序中实例化两个(或者更多)调度器,并在这两个(或者更多)调度器上调度job,并且只有一个job被放在本地机器上运行的某个调度器中。这可以在你想要执行job的进程中调用scheduler.start()来实现。scheduler.start()让scheduler实例开始处理jobs(如开始等待触发器触发时间到达,然后再在开始执行)。但是一个未启动的scheduler实例仍然用来调度(和恢复)作业。

例子:

  • 在”APP A”中创建”Scheduler A”(该配置将它指向以”A”为前缀的数据库表),然后”Scheduler A”调用start()。现在”APP A”的”Scheduler A”将会执行被”Scheduler A”调度的jobs。
  • 在”APP A”中创建”Scheduler B”(该配置将它指向以”B”为前缀的数据库表),然后”Scheduler B”不调用start()。现在”APP A”的”Scheduler B”将会执行被”Scheduler B”启动后调度的jobs。
  • 在”APP A”中创建”Scheduler B”(该配置将它指向以”B”为前缀的数据库表),然后”Scheduler B”调用start()。现在”APP A”的”Scheduler B”将会执行被”Scheduler B”调度的jobs。

6. 列出调度器中的Jobs

  1. // 遍历每个Job组
  2. for(String group: sched.getJobGroupNames()) {
  3. // 遍历每个Job组里的Job
  4. for(JobKey jobKey : sched.getJobKeys(groupEquals(group))) {
  5. System.out.println("Found job identified by: " + jobKey);
  6. }
  7. }

7. 列出调度其中的Triggers

  1. // enumerate each trigger group
  2. for(String group: sched.getTriggerGroupNames()) {
  3. // enumerate each trigger in group
  4. for(TriggerKey triggerKey : sched.getTriggerKeys(groupEquals(group))) {
  5. System.out.println("Found trigger identified by: " + triggerKey);
  6. }
  7. }