方案一:基于@Scheduled注解的定时任务,修改定时规则需要修改代码,修改后需要重启项目
@EnableScheduling //这个注解的作用就是开启定时任务功能
@Component
@Slf4j
public class ScheduleTask {
@Scheduled(cron = "0/5 * * * * ?")
private void configureTasks() {
log.info("执行定时任务时间: " + LocalDateTime.now());
}
}
方案二:基于@EnableAsync的多线程定时任务
@EnableScheduling //1.这个注解的作用就是开启定时任务功能
@EnableAsync // 2.开启异步多线程
@Component
public class MultithreadScheduleTask {
@Async
@Scheduled(fixedDelay = 2000) //间隔2秒
public void first() throws InterruptedException {
System.out.println("第一个定时任务开始 : " + LocalDateTime.now().toLocalTime() + "\r\n线程 : " + Thread.currentThread().getName());
TimeUnit.SECONDS.sleep(1);
}
@Async
@Scheduled(fixedDelay = 1000)//间隔1秒
public void second() {
System.out.println("第二个定时任务开始 : " + LocalDateTime.now().toLocalTime() + "\r\n线程 : " + Thread.currentThread().getName());
}
}
方案三:动态定时任务,在数据库中查询定时规则,可以随时改变定时任务的执行规则
@Configuration
@EnableScheduling
public class DynamicScheduleTask implements SchedulingConfigurer {
@Autowired
private ScheduleServiceInter scheduleService;
@Override
public void configureTasks(ScheduledTaskRegistrar scheduledTaskRegistrar) {
//定时任务
Runnable task = () -> System.out.println("执行动态定时任务: " + LocalDateTime.now().toLocalTime());
//设置定时任务执行间隔
scheduledTaskRegistrar.addTriggerTask(
//1.添加任务内容(Runnable)
task,
//2.设置执行周期(Trigger)
triggerContext -> {
//2.1 从数据库获取执行周期
CronEntity cron = scheduleService.getCron("1");
//2.2 合法性校验.
if (StringUtils.isEmpty(cron)) {
// Omitted Code ..
}
//2.3 返回执行周期(Date)
return new CronTrigger(cron.getCron()).nextExecutionTime(triggerContext);
}
);
}
}
方案四:基于线程池的多线程定时任务
@Component
@EnableScheduling //1.这个注解的作用就是开启定时任务功能 利用springtask即时spring的自己的技术
@EnableAsync // 2.开启多线程
@Slf4j
public class ExecutorScheduledTask {
/**
* 注解@Async里的"taskExecutor",就是ScheduledConfig里定义的bean: public Executor taskExecutor()
*/
@Async("taskExecutor")
@Scheduled(cron = "${cash.template.taskTime}")
public void query() throws InterruptedException {
log.info("-----------开始查询任务-----------");
//记录当前任务开始时间
LocalDateTime startTime = LocalDateTime.now();
//模拟任务处理
TimeUnit.SECONDS.sleep(3);
//记录当前任务结束时间
LocalDateTime endTime = LocalDateTime.now();
//计算两个时间的毫秒差
long millis = ChronoUnit.MILLIS.between(startTime, endTime);
log.info("执行任务耗时:{}毫秒", millis);
log.info("-----------结束查询任务-----------");
}
}
方案五:使用ScheduledThreadPoolExecutor定时任务线程池执行定时任务
@Component
public class ScheduledThreadPoolExecutorTest {
@Autowired
private ScheduledThreadPoolExecutor scheduledThreadPoolExecutor;
@Bean
public void test(){
scheduledThreadPoolExecutor.scheduleAtFixedRate(()->{
System.out.println(LocalDateTime.now().toLocalTime() + Thread.currentThread().getName() + " hello world1");
},3,6, TimeUnit.SECONDS);
scheduledThreadPoolExecutor.scheduleAtFixedRate(()->{
System.out.println(LocalDateTime.now().toLocalTime() + Thread.currentThread().getName() + " hello world2");
},3,6, TimeUnit.SECONDS);
scheduledThreadPoolExecutor.scheduleAtFixedRate(()->{
System.out.println(LocalDateTime.now().toLocalTime() + Thread.currentThread().getName() + " hello world3");
},3,6, TimeUnit.SECONDS);
scheduledThreadPoolExecutor.scheduleAtFixedRate(()->{
System.out.println(LocalDateTime.now().toLocalTime() + Thread.currentThread().getName() + " hello world4");
},3,6, TimeUnit.SECONDS);
}
}