前段时间,写了一个定时器,但是部署到生成环境上面是多实例的,所以会多次执行。
在这里借用Redis实现,只执行一次定时器任务。
@Autowired
private StringRedisTemplate redisTemplate;//redis操作模板
/**
* 数据库分布锁
*
* @return
*/
public synchronized Boolean setLock() {
logger.info("开始加锁");
/*该方法会在没有key时,设置key;存在key时返回false;因此可以通过该方法及设置key的有效期,判断是否有其它线程持有锁*/
//key 随意设置,但是要和下方保持一致,你也可以选择传参key进来,自行决定
Boolean methodLock = redisTemplate.opsForValue().setIfAbsent("CCScheduleMethodLock", System.currentTimeMillis() + "");
if (methodLock) {
logger.info("加锁成功");
//加锁,设置过期时间
redisTemplate.expire("CCScheduleMethodLock", 100, TimeUnit.SECONDS);
} else {
logger.info("未加锁");
}
return methodLock;
}
在执行逻辑处理的时候调用一下这个方法就行了,例如:
/**
* 预警定时任务,每天10点检查是否有小程序即将到期并通知用户
*/
@Scheduled(cron = "0 0 10 * * ?")
public void alertSchedule() {
Boolean status= redisUtil.setLock();
if(status){
//定时器第一次执行,这里处理逻辑
}
}