一、核心总结二、纯注解方式三、代码方式
一、核心总结01.纯注解 VS 代码
纯注解方式:简单+异步(同一任务之间也可多线程)
代码方式:可控制定时任务的开启、关闭,可实时更新cron表达式,仅不同任务之间的多线程
仍存的问题:task如何同时满足异步、开启关闭、实时更新的方式?
02.核心代码
a.开启关闭
//【创建定时任务线程池】 ThreadPoolTaskScheduler pool = new ThreadPoolTaskScheduler(); pool.initialize(); //使用前需初始化下,默认核心线程为1 //【开启】这个支持cron表达式 ScheduledFuture> future = pool.schedule(runnable, new CronTrigger(cron表达式) ); //【关闭】 future.cancel(true);
a.动态读取
将上面的
new CronTrigger(cron表达式)
改为
(executionTime)->{return new CronTrigger(cron表达式).nextExecutionTime(executionTime)
区别:
更改前,在同一个任务中只会调用一次cron字符串;
更改后,在同一任务的每个执行时间截点都会调用一次
故可据此将cron表达式改成一个读取最新cron表达式的方法
例如:
a.调用dao接口从数据库读取cron表达式;
b.从yml中读取,yml修改后结合actuator的@RefreshScope方式主动更新(nacos更好);
c,读取某个excel里的cron表达式
开启定时任务,比放在启动类上 @EnableScheduling //@EnableAsync //开启异步,保证每次执行都是独立线程 ★ 启动类 @Scheduled(cron = "0/5 * * * * ?", //秒 分 时 日 月 周 initialDelay = 2000, //首次任务启动的延迟时间 fixedDelay = 2000, //上次任务end——>下次任务start 的时间间隔 fixedRate = 2000 //两次任务的start时间间隔(毫秒) ) //@Async //开启多线程 ★ 要定时执行的方法
如需调整其他参数,可参考这里
三、代码方式简易工具类
MyTaskUtil
package org.lm.task;
import cn.hutool.core.date.DateUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
@RestController
@Slf4j
public class TestController {
@Autowired
private MyTaskUtil myTaskUtil;
@GetMapping("/start")
public String startInCron(
@RequestParam(required = false,defaultValue = "* * * * * ?") String cron,
@RequestParam(required = false) String taskName
){
return myTaskUtil.startInCron(
() -> {
System.out.println(taskName+" "+Thread.currentThread().getName()+" 记录当前时间:"+ DateUtil.now());
},
cron,
taskName);
}
@GetMapping("/cancel")
public String cancel(@RequestParam String taskName){
return myTaskUtil.cancel(taskName);
}
@GetMapping("/cancel2")
public String cancelLast(){
return myTaskUtil.cancelLast();
}
@GetMapping("/list")
public String findTaskList(){
List list = myTaskUtil.findTaskList();
String CRLF="rn";
StringBuffer sb = new StringBuffer("总数为:"+list.size());
for (TaskBean bean : list) {
sb.append(CRLF).append(bean.toString());
}
System.out.println(sb.toString());
return sb.toString();
}
@GetMapping("/reset")
public String reset(@RequestParam(required = false) String cron, @RequestParam String taskName ){
return myTaskUtil.reset(cron,taskName);
}
@GetMapping("/reset2")
public String reset2(@RequestParam(required = false) String cron, @RequestParam String taskName ){
Runnable runnable=()->{
System.out.println(taskName+" "+DateUtil.now()+"扫描库存为:"+(++count));
};
return myTaskUtil.reset(runnable,cron,taskName);
}
private int count=0; //库存
}



