Job并发
Job是有可能并发的,比如一个任务要执行10秒,而调度算法是每秒钟触发1次,那么就有可能多个任务被并发执行。
有时候我们并不想任务并发执行,比如这个任务要去『获得数据库中所有未发送邮件的名单』,如果是并发执行,就需要一个数据库锁去避免一个数据被多次处理。
这个时候就需要一个@DisallowConcurrentExecution解决问题。
@DisallowConcurrentExecution
public class DoNothingJob implements Job {
@Override
public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
try {
TimeUnit.SECONDS.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("操作");
}
}
public static void main(String[] args) throws SchedulerException {
Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler();
TriggerBuilder triggerBuilder = TriggerBuilder.newTrigger();
Trigger trigger = triggerBuilder.withIdentity("trigger1", "group1")//定义name/group
.startNow()//一旦加入scheduler立即生效,即开始时间
.withSchedule(CronScheduleBuilder.cronSchedule("0/2 * * * * ?")).build();
JobDetail job = JobBuilder.newJob(DoNothingJob.class)
.withIdentity("测试任务1", "test")//定义name/group
.usingJobData("data", "jobData_xxxxxx")//定义属性,存储数据
.build();
//调度器中假如任务和触发器
scheduler.scheduleJob(job, trigger);
//启动任务调度
scheduler.start();
try {
TimeUnit.SECONDS.sleep(5);
} catch (InterruptedException e) {
e.printStackTrace();
}
//关闭调度器
// scheduler.shutdown();
}
实际并不会2秒执行一次,而是会根据任务具体执行时间而定(每隔一个时间间隔检查一下任务是否执行完毕,如果没有就再等一个时间间隔)。
注意: @DisallowConcurrentExecution是对JobDetail实例生效,也就是如果你定义两个JobDetail,引用一个Job类,是可以并发执行的。
本文深入探讨了Job并发执行的问题,特别是在任务需要长时间运行且调度频率较高的场景下。通过使用@DisallowConcurrentExecution注解,可以有效防止任务的并发执行,避免数据库锁竞争,确保数据一致性。文章还提供了一个具体的实现示例,展示了如何在实际代码中应用此注解。
761

被折叠的 条评论
为什么被折叠?



