1.springBoot配置定时任务
1.1 主函数入口添加 @EnableScheduling 注解
@SpringBootApplication
@EnableScheduling
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}
1.2 方法上添加注解@Scheduled,设置每天凌晨0点执行
@Scheduled(cron="0 0 * * *")
public void execute(){
}
2.集成redis
@Autowired
private RedisTemplate redisTemplate;
使用redisTemplate 的 setIfAbsent方法(该方法是setnx命令的实现),来模拟是否获取到锁
如果返回true,则说明该key值不存在,表示获取到锁;如果返回false,则说明该key值存在,已经有程序在使用这个key值了
redisTemplate.opsForValue().setIfAbsent(key, value);
3.示例代码:
@Autowired
private RedisTemplate redisTemplate;
/**
* redis定时任务的key
*/
public static final String REDIS_TASK_JOB_LOCK_KEY = "REDIS_TASK_JOB_KEY";
/**
* redis定时任务的value
*/
public static final String REDIS_TASK_JOB_LOCK_VALUE = "REDIS_TASK_JOB_VALUE";
@Scheduled(cron="0 0 * * *")
public void execute() {
StaticLog.info("GCP XXXXX 定时任务开启......");
// 定义加锁状态
boolean lock = false;
try {
lock = redisTemplate.opsForValue().setIfAbsent(REDIS_TASK_JOB_LOCK_KEY, REDIS_TASK_JOB_LOCK_VALUE);
if (lock) {
// 该key值不存在,获取到锁
System.out.println("调用了定时任务....." + DateUtil.now());
// 根据项目id并发处理项目
CompletionService<Boolean> cs = ThreadUtil.newCompletionService();
ArrayList<Integer> projectIdList = ListUtil.toList(1, 2, 3);
for (Integer projectId : projectIdList) {
// 提交任务
cs.submit(() -> doAction1(projectId));
}
System.out.println("定时任务结束时间....." + DateUtil.now());
}
} catch (Exception e) {
StaticLog.error("GCP XXXXX 定时任务异常......", e);
} finally {
if (lock) {
// 释放锁
redisTemplate.delete(REDIS_TASK_JOB_LOCK_KEY);
}
}
}
private Boolean doAction1(Integer projectId) {
// 根据项目ID执行核心业务逻辑
ThreadUtil.sleep(10000);
return true;
}