java quartz 設置定時任務串行執行


下面以一個簡單的quartz定時任務為例說明如何設置定時任務串行執行(在很多場景下我們是想讓一個定時任務跑完后再跑下一個任務的),首先看默認的定時任務如何執行:

Job類:

package quartzDemo;

import cn.hutool.core.date.DateUtil;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;

public class JobDemo implements Job {
    @Override
    public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
        System.out.println(DateUtil.now() + ": " + "into job" + "---thread: " + Thread.currentThread().getId());
        try {
            Thread.sleep(5000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println(DateUtil.now() + ": " + "finish job" + "---thread: " + Thread.currentThread().getId());

    }
}

執行類:

package quartzDemo;

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

public class Demo {

    public static void main(String[] args) throws SchedulerException {

        JobDetail jobDetail = JobBuilder.newJob(JobDemo.class).withIdentity("myJob", "myGroup").build();
        CronTrigger trigger = TriggerBuilder.newTrigger().withIdentity("myTrigger", "myGroup").startNow().withSchedule(CronScheduleBuilder.cronSchedule("0/2 * * * * ? ")).build();
        SchedulerFactory schedulerFactory = new StdSchedulerFactory();
        Scheduler scheduler = schedulerFactory.getScheduler();
        scheduler.scheduleJob(jobDetail, trigger);
        scheduler.start();
    }
}

運行結果:

2021-10-10 21:43:56: into job---thread: 12
2021-10-10 21:43:58: into job---thread: 13
2021-10-10 21:44:00: into job---thread: 14
2021-10-10 21:44:02: into job---thread: 15
2021-10-10 21:44:02: finish job---thread: 12
2021-10-10 21:44:03: finish job---thread: 13
2021-10-10 21:44:04: into job---thread: 16
2021-10-10 21:44:05: finish job---thread: 14
2021-10-10 21:44:06: into job---thread: 17
2021-10-10 21:44:07: finish job---thread: 15
2021-10-10 21:44:08: into job---thread: 18
2021-10-10 21:44:09: finish job---thread: 16

結論:

默認情況下,每個定時任務都會開啟一個新的線程(線程池中的線程,損耗並不大),而且如果任務執行時間過長(5s),超過定時任務的間隔(2s)時,任務是會並行執行的(即不會等上一個任務執行完成后再執行下一個任務)。

那如何設置任務串行執行呢,加上@DisallowConcurrentExecution注解,job類如下:

package quartzDemo;

import cn.hutool.core.date.DateUtil;
import org.quartz.DisallowConcurrentExecution;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;

@DisallowConcurrentExecution
public class JobDemo implements Job {
    @Override
    public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
        System.out.println(DateUtil.now() + ": " + "into job" + "---thread: " + Thread.currentThread().getId());
        try {
            Thread.sleep(5000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println(DateUtil.now() + ": " + "finish job" + "---thread: " + Thread.currentThread().getId());

    }
}

運行結果:

2021-10-10 21:49:50: into job---thread: 14
2021-10-10 21:49:55: finish job---thread: 14
2021-10-10 21:49:55: into job---thread: 15
2021-10-10 21:50:00: finish job---thread: 15
2021-10-10 21:50:00: into job---thread: 16
2021-10-10 21:50:05: finish job---thread: 16
2021-10-10 21:50:05: into job---thread: 17

結論:

各任務是串行執行的(雖然不同任務跑在不同的線程中),即上一個任務執行完后再執行下一個任務。

 

另外:

@PersistJobDataAfterExecution 加在Job上,表示當正常執行完Job后, JobDataMap中的數據應該被改動, 以被下一次調用時用。當使用@PersistJobDataAfterExecution 注解時, 為了避免並發時, 存儲數據造成混亂, 建議把@DisallowConcurrentExecution注解也加上。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM