【企業級定時任務Quartz】---如何防止定時任務併發

前言

最近項目中在使用企業級定時任務Quartz,在使用過程中,發現一個問題就是我們如何防止定時任務的併發?


定時任務的併發

  • 正常執行
    在這裏插入圖片描述
  • 併發
    在這裏插入圖片描述
    通過上面的圖片,我們瞭解了併發任務,在實際的項目開發中,如何防止併發呢?
    @DisallowConcurrentExecution 防止併發

模擬併發


package com.zcw;

import com.zcw.job.MyJob;
import org.quartz.*;
import org.quartz.impl.StdSchedulerFactory;

/**
 * @ClassName : QuartzDemo
 * @Description :啓動類
 * @Author : Zhaocunwei
 * @Date: 2020-06-09 13:31
 */
public class QuartzDemo {
    public static void main(String[] args) throws SchedulerException {
        Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler();
        scheduler.start();
        //配置任務
        JobDetail jobDetail = JobBuilder.newJob(MyJob.class)
                .withIdentity("jobDetail1","group1")
                .usingJobData("name","zcw")
                .build();
        //創建觸發器
        Trigger trigger = TriggerBuilder.newTrigger()
                .startNow()
                .withSchedule(SimpleScheduleBuilder.simpleSchedule()
                //時間間隔爲5秒
                .withIntervalInSeconds(5)
                .repeatForever()
                ).build();

        scheduler.scheduleJob(jobDetail,trigger);

        try {
            Thread.sleep(600000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        scheduler.shutdown();
    }
}


  • job類
package com.zcw.job;

import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.quartz.*;

import java.time.LocalTime;

/**
 * @ClassName : MyJob
 * @Description :
 * @Author : Zhaocunwei
 * @Date: 2020-06-09 13:32
 */
@Data
public class MyJob implements Job {

    private String name;


    @Override
    public void execute(JobExecutionContext context) throws JobExecutionException {
        LocalTime localTime = LocalTime.now();
        System.out.println(Thread.currentThread().getName()+"開始執行!"+localTime.toString());
        try {
            Thread.sleep(7000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        LocalTime endTime = LocalTime.now();
        System.out.println("結束時間!"+endTime.toString());

    }
}

  • 測試結果
    在這裏插入圖片描述

優化代碼,解決併發添加註解

package com.zcw.job;

import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.quartz.*;

import java.time.LocalTime;
import java.util.concurrent.ThreadPoolExecutor;

/**
 * @ClassName : MyJob
 * @Description :
 * @Author : Zhaocunwei
 * @Date: 2020-06-09 13:32
 */
@Data
@DisallowConcurrentExecution
public class MyJob implements Job {

    private String name;


    @Override
    public void execute(JobExecutionContext context) throws JobExecutionException {
        LocalTime localTime = LocalTime.now();
        System.out.println(Thread.currentThread().getName()+"開始執行!"+localTime.toString());
        try {
            Thread.sleep(7000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        LocalTime endTime = LocalTime.now();
        System.out.println(Thread.currentThread().getName()+"結束時間!"+endTime.toString());

    }
}


在這裏插入圖片描述

  • 測試
    在這裏插入圖片描述

JobDataMap的更新

在這裏主要是演示一個@PersistJobDataAfterExecution可更新JobDataMap註解,把數據持久化到我們的jobDataMap中。

在這裏插入圖片描述
在這裏插入圖片描述

  • 測試
    在這裏插入圖片描述
    通過上面的演示,我們的count值沒有增加,需要每次執行一次count+1;
    在這裏插入圖片描述

package com.zcw.job;

import lombok.Data;
import org.quartz.*;

import java.time.LocalTime;

/**
 * @ClassName : MyJob
 * @Description :
 * @Author : Zhaocunwei
 * @Date: 2020-06-09 13:32
 */
@Data
@PersistJobDataAfterExecution
public class MyJob implements Job {

    private int count;


    @Override
    public void execute(JobExecutionContext context) throws JobExecutionException {
        LocalTime localTime = LocalTime.now();
        count++;
        context.getJobDetail().getJobDataMap().put("count",count);
        System.out.println(localTime.toString()+",count值="+count);


    }
}


  • 測試
    在這裏插入圖片描述
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章