定时任务的并发_03
程序员文章站
2024-03-22 17:02:52
...
正常定时任务场景
任务1从第0秒开始执行,执行3秒结束
任务1再从第5秒开始执行,执行3秒结束,以此类推
每一个任务执行都不会有冲突,都不会有干扰,在规定的5秒时间内,任务1都能执行完成
定时任务的并发场景
什么是定时任务的并发?
任务2从第0秒开始执行,执行7秒结束,这个定时任务
任务2再从第5秒开始执行,这时第一个定时任务由于数量大尚未执行完成,任务2 开始第2次任务开始,执行7秒结束,但是,任务2执行的第一次和执行第二次有重叠部分,这一部分成为定时任务的并发,这一部分有可能处理相同的数据。
案例理解:在定时定点给一个用户发短信,一个用户只发一次,如果是定时任务并发,有可能给同一个用户发送2次短信
定时任务并发代码演示:
package com.gblfy.job;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import java.time.LocalTime;
public class MyJob implements Job {
@Override
public void execute(JobExecutionContext context) throws JobExecutionException {
LocalTime localTime = LocalTime.now();
System.out.println(Thread.currentThread().getName()+"开始执行!" + localTime);
try {
//休眠7秒
Thread.sleep(7000);
} catch (InterruptedException e) {
e.printStackTrace();
}
LocalTime endTime = LocalTime.now();
System.out.println(Thread.currentThread().getName()+"结束执行!" + endTime);
}
}
找一组分析一下:
Worker-1开始执行!17:55:08
Worker-2开始执行!17:55:12
Worker-1结束执行!17:55:15
Worker-3开始执行!17:55:17
Worker-2结束执行!17:55:19
Worker-1开始执行!17:55:22
Worker-3结束执行!17:55:24
定时任务并发数据开始分析:
Worker-1和Worker-2 开始执行间隔5秒
Worker-1 开始执行和Worker-1 结束执行 间隔7秒
Worker-2和Worker-3 开始执行间隔5秒
Worker-2 开始执行和Worker-2 结束执行 间隔7秒
Worker-3和Worker-1 开始执行间隔5秒
Worker-3 开始执行和Worker-3 结束执行 间隔7秒
如何防止定时任务并发?
在Job类上添加@DisallowConcurrentExecution注解
防止并发示例
package com.gblfy.job;
import org.quartz.DisallowConcurrentExecution;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import java.time.LocalTime;
@DisallowConcurrentExecution
public class MyJob implements Job {
@Override
public void execute(JobExecutionContext context) throws JobExecutionException {
LocalTime localTime = LocalTime.now();
System.out.println(Thread.currentThread().getName() + "开始执行!" + localTime);
try {
//休眠7秒
Thread.sleep(7000);
} catch (InterruptedException e) {
e.printStackTrace();
}
LocalTime endTime = LocalTime.now();
System.out.println(Thread.currentThread().getName() + "结束执行!" + endTime);
}
}
找一组分析一下:
Worker-1开始执行!18:08:17
Worker-1结束执行!18:08:24
Worker-2开始执行!18:08:24
Worker-2结束执行!18:08:31
Worker-3开始执行!18:08:31
Worker-3结束执行!18:08:38
Worker-1开始执行!18:08:42
Worker-1结束执行!18:08:49
定时任务并发数据开始分析:
Worker-1 开始执行和结束执行 间隔7秒
Worker-2 开始执行和结束执行 间隔7秒
Worker-3 开始执行和结束执行 间隔7秒
Worker-2 第一次执行应该是 Worker-2开始执行!18:08:22,但是由于Worker-1还没有结束,等待Worker-1执行完成后,Worker-2开始执行
Worker-3 第一次执行应该是 Worker-3开始执行!18:08:27,但是由于Worker-2 还没有结束,等待Worker-2执行完成后,Worker-3开始执行
Worker-1 第二次执行应该是 Worker-1 开始执行!18:08:32,但是由于Worker-3 还没有结束,等待Worker-3 执行完成后,Worker-1开始执行,单这次定时任务会触发Qartz的Misfire的错过机制,等到下一个节点执行第2次的Worker-1
Worker-3结束执行!18:08:38
Worker-1开始执行!18:08:42
从以上数据,可以看出,当地二次执行 Worker-1时,按照上面的规则应该是Worker-1开始执行!18:08:38,对吧?
第1次错过:执行Worker-2
第2次错过:执行Worker-3
当错过2次定时任务,就会Qartz的Misfire的错过机制
Qartz的Misfire的错过机制:
当定时任务错过2次,之后会触发Qartz的Misfire的错过机制,触发及之后,上面的错过的2次定时任务会取消,等到下一个节点执行定时任务。