
在java项目中常常用到定时任务如果在项目一开始的情况下就需要将定时任务启动这个需要怎么做呢今天就让我来写一个小demo吧。凑合看吧import io.jsonwebtoken.lang.Collections; import org.quartz.*; import org.springframework.stereotype.Component; import javax.annotation.PostConstruct; import javax.annotation.Resource; import java.util.List; Componet public class JobInitializer{ Resource private Scheduler scheduler; //自己的业务mapper Resource prtivate BusinessScheduledMapper businessScheduledMapper; //ScheduledDto也是自己项目中的 Resource prtivate ScheduledLockMapper ScheduledLockMapper ; PostConstruct public void initJobs() throws ClassNotFoundException,SchedulerException{ //在数据库中配置了所有的定时任务cros ListScheduledDto list businessScheduledMapper.findAll(); if(Collections.isEmpty(list)){ return ; } for(ScheduledDto s : list){ Class? extends Job jobClazz (Class? extends Job ) Class.forName(s.getJobClass()); JobDetail jobDetail JobBuilder.newJob(jobClazz).withIdentity(s.getJobName()).storeDurably().build(); CronTrigger cronTrigger TriggerBuilder.newTrigger() .withIdentity(s.getTriggerName()) .startNow() .withSchedule(CronScheduleBuilder.cronSchedule(s.getCron()))\ .build(); scheduler.scheduileJob(jobDetail,cronTrigger); } if(!schedule.isShutdown()){ scheduler.start(); } } }import org.quartz.DisallowConcurrentExecution; import org.quartz.Job; import org.quartz.JobExecutionException; import org.quartz.JobExecutionContext; import org.springframework.stereotype.Component; import java.time.LocalDateTime; //禁止并发执行 Component DisallowConcurrentExecution public class Complex implements Job{ Override public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException{ System.out.prientln(RAMJobStor复杂执行LocalDateTime.now()); } }import org.springfremework.context.annotation.Bean; import org.springfremework.context.annotation.Configuration; import org.springfremework.scheduling.concurrent.ThreadPoolTaskScheduler; //定时任务线程池配置 Configuration public class SchedulerTaskConfig{ Bean(handConfigTaskScheduler) public ThreadPoolTaskScheduler threadPoolTaskScheduler (){ return new ThreadPoolTaskScheduler(); } }让我们来写一个可运行的例子吧package com.meet.scheduler.job; Slf4j DisallowConcurrentExecution Component public class AScheduler implements Job{ Resource private BusinessSchedulerLockService businessSchedulerLockService; //业务服务 Resource private BusinessService BusinessService; Override public void execute(JobExecutionContext jobExecutionContext) throws JobWxcutionException{ //这里有个乐观锁先验证是否有锁的信息如果没有就插入有就返回 SchedulerLock schedulerLock businessSchedulerLockService.selectByLockName(updateStatus); //直接更新锁如果更新条数为1则说明抢锁成功。将锁状态改为1 int rst schedulerLockService.updateLockStatusUsed(schedulerLock); if(rst 1){ log.info(抢到锁开始执行任务); try{ Thread.sleep(5000); log.info(任务开始); businessService.updateStatus(Constatnt.START,schedulerLock); log.info(任务结束); }catch(InterruptedException e){ throw new RuntimeException(e); } }else { log.info(获取锁失败本次放弃拉取); } } }在业务服务的实现类中直接实现update的方法public class BusinessServiceImpl implements BusinessService{ Override public void updateStatus(Integer archived, SchedulerLock schedulerLock){ try{ //业务代码 businessMapper.updateStatus(archived); }catch(Exception e){ e.printStATCKtRACE(); }finally{ //无论怎样最后的方法都会执行,执行修改锁的状态改为0的sql businessSchedulerLockService.updateLockStatusReleased(schedulerLock); } }看看BusinessSchedulerLockService中是怎么写的呢Slf4j Service Transactional public class BusinessSchedulerLockService{ Resource private BusinessSchedulerLockMapper businessSchedulerLockMapper; public SchedulerLock selectByLockName(String lockName){ QueryWrapperSchedulerLock queryWapper new QueryWrapper(); queryWrapper.eq(lock_name,lockName); SchedulerLock schedulerLock businessSchedulerLockMapper.selectOne(queryWrapper); if( schedulerLock null || schedulerLock.getLockName null){ SchedulerLock lock new SchedulerLock(); lock.setLockId(UUID.fastUUID().toString()); lock.setLockName(lockName); lock.setLockStatus(0); businessSchedulerLockMapper.insert(lock); return lock; } //没有就加有了就直接返回查询的。 return schedulerLock; } public int updateLockStatusUsed(SchedulerLock schedulerLock){ int rst businessSchedulerLockMapper.updateStatus(schedulerLock.getLockName(),1); return rst; } public void updateLockStatusReleased(SchedulerLock schedulerLock){ businessSchedulerLockMapper.updateStatus(schedulerLock.getLockName(),0); } }在application.yml中还需要添加核心线程数这些spring: task: execution: pool: core-size: 5 #核心线程数最小线程数 max-size: 10 #最大线程数 queue-capacity: 20 #任务队列容量 keep-alive: 60s #线程空闲存活的时间定时任务的实体类在项目启动的时候需要查询这个表中的所有定时任务。 public class BusinessScheduled{ private String schedulerdId; private String scheduledName; private String jobClass; private String jobName; private String triggerName; private String jobStatus; private String cron; }数据库中BusinessScheduled中所对应的值给个参考schedulerdId随机id可以uuid也可以自增scheduledName定时任务名称比如修改材料状态。jobClass是指定时任务具体是哪个类写全路径com.meet.scheduler.job.ConferenceScheduler 。jobStatus状态0不开启1开启jobName和triggerName可以自己起也可生成一个随机的。写一样的也行。cron是最重要的比如是每分钟定时任务运行一次都需要配置在这里才可以。scheduler_lock表中只有三个字段lock_idlock_name,lock_status在项目启动执行定时任务时会自动加入scheduler_lock表中lockstatus的状态默认是0后续如果在进行中就会修改为1执行完成之后会将状态再次改为0。