提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
前言
`前提,项目部署在多个节点,业务需求单位时间内存在一个调度,且严格按照顺序执行,【锁时间需严格把控】
一、实现
@RestController
public class RedisController {
public static final Logger log = LoggerFactory.getLogger(RedisController.class);
@Resource
private RedisTemplate<String, String> redisStringTemplate;
private static final String KEY = "KEY_";
private static final String VALUE = "VALUE_";
private static final long LOCK_TIME_MILLISECONDS = 5 * 60 * 1000;
private static final Long SUCCESS = 1L;
private Boolean tryLock(){
Long start = System.currentTimeMillis();
for (;;){
Boolean absent = redisStringTemplate.opsForValue().setIfAbsent( KEY, VALUE,LOCK_TIME_MILLISECONDS,
TimeUnit.MILLISECONDS );
if(absent){
return Boolean.TRUE;
}
long end = System.currentTimeMillis() - start;
if(end >= LOCK_TIME_MILLISECONDS){
return Boolean.FALSE;
}
}
}
private void unlock() {
try {
Object result = redisTemplate.delete(Collections.singletonList(KEY));
if (SUCCESS.equals(result)) {
logger.info("释放锁成功");
}
} catch (Exception e) {
logger.error("释放锁失败");
}
}
@Scheduled(cron = "0 */3 * * * *")
public void task() {
if(!tryLock()){
logger.error("获取锁失败");
return;
}
try{
}catch (Exception e) {
logger.error("异常:{}",e.getMessage(), e);
}
unlock();
}
}
总结
提示:业务处理时间需要把控,一旦超过key的存活时间限制,锁就会被释放,看业务而定。
|