読者です 読者をやめる 読者になる 読者になる

覚えたら書く

IT関係のデベロッパとして日々覚えたことを書き残したいです。 twitter: @yyoshikaw

Quartz - Javaで定期処理を行いたい

Javaで定期処理を書くのは、Java標準のAPIを使ってできるのはできますが、
ジョブスケジューラライブラリのQuartzというものが存在しています

これを使ったほうがもっとシンプルに書けて、(たぶん)高機能なこともできます。

とりあえずまずは使ってみましょう。


準備

pom.xmlに依存関係を以下の通りに追加します。

<dependency>
    <groupId>org.quartz-scheduler</groupId>
    <artifactId>quartz</artifactId>
    <version>2.2.3</version>
</dependency>


ジョブを定義する

org.quartz.Jobインターフェースを実装したクラスを作成し、executeメソッドをオーバーライドしてそこに定期的に実行したい処理を実装します

import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;

public class SampleJob implements org.quartz.Job {

    public SampleJob() {
    }

    public void execute(JobExecutionContext context) throws JobExecutionException {
        System.out.println(Thread.currentThread().getName() + " : SampleJob is execute.");
    }
}


スケジューリングの定義を行う

定義したジョブをどういうスケジュールで実行するかを定義します。

基本的に以下のような流れになります

  1. 定義したジョブのクラスをもとにしてJobBuilderを利用してJobDetailを生成する
  2. TriggerBuilderを用いて、実行間隔などを定義したTriggerを作成する
  3. Scheduler#scheduleJobで、作成したJobbDetailTriggerを(ジョブとしてスケジュール)登録する
  4. Scheduler#startを実行してジョブスケジュールと開始する

こうすると定義したジョブが定期的に実行されます
(実際には上に書いた処理の流れは前後していいところもあります。例えば3と4は別に逆になっててもいいです)

import org.quartz.*;
import org.quartz.impl.StdSchedulerFactory;

import static org.quartz.SimpleScheduleBuilder.simpleSchedule;

public class QuartzTrialMain {

    public static void main(String[] args) {

        JobDetail job = JobBuilder.newJob(SampleJob.class)
                .withIdentity("job1", "group1")
                .build();

        Trigger trigger = TriggerBuilder.newTrigger()
                .withIdentity("trigger1", "group1")
                .startNow()
                .withSchedule(simpleSchedule()
                        .withIntervalInMilliseconds(100)   // 100ミリ秒間隔
                        .repeatForever())                  // 処理をずっと繰り返す
                .build();


        Scheduler scheduler = null;
        try {
            scheduler = StdSchedulerFactory.getDefaultScheduler();
            scheduler.scheduleJob(job, trigger);

            scheduler.start();
        } catch (SchedulerException e) {
            throw new RuntimeException(e);
        }


        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        try {
            scheduler.shutdown();
        } catch (SchedulerException e) {
            throw new RuntimeException(e);
        }

        System.out.println("QuartzTrialMain#main end");
    }
}


■実行結果

(100ミリ秒間隔で)定期的にSampleJobクラスで実装した処理が実行されています。

DefaultQuartzScheduler_Worker-1 : SampleJob is execute.
DefaultQuartzScheduler_Worker-2 : SampleJob is execute.
DefaultQuartzScheduler_Worker-3 : SampleJob is execute.
DefaultQuartzScheduler_Worker-4 : SampleJob is execute.
DefaultQuartzScheduler_Worker-5 : SampleJob is execute.
DefaultQuartzScheduler_Worker-6 : SampleJob is execute.
DefaultQuartzScheduler_Worker-8 : SampleJob is execute.
DefaultQuartzScheduler_Worker-7 : SampleJob is execute.
DefaultQuartzScheduler_Worker-9 : SampleJob is execute.
DefaultQuartzScheduler_Worker-10 : SampleJob is execute.
DefaultQuartzScheduler_Worker-1 : SampleJob is execute.
DefaultQuartzScheduler_Worker-3 : SampleJob is execute.
DefaultQuartzScheduler_Worker-2 : SampleJob is execute.
DefaultQuartzScheduler_Worker-4 : SampleJob is execute.
DefaultQuartzScheduler_Worker-5 : SampleJob is execute.
DefaultQuartzScheduler_Worker-6 : SampleJob is execute.
DefaultQuartzScheduler_Worker-8 : SampleJob is execute.
QuartzTrialMain#main end


というわけで、簡単に定期処理を実行することができました。
実際にはQuartzではもっと細かい設定などもできます。それは次(?)の機会に書きたいと思います



関連エントリ