Redis锁简单实现

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档

文章目录

  • 前言
  • 一、实现
  • 总结


前言

前提,项目部署在多个节点,业务需求单位时间内存在一个调度,且严格按照顺序执行,【锁时间需严格把控】

一、实现

@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{
			// TODO dosomething
		}catch (Exception e) {
			logger.error("异常:{}",e.getMessage(), e);
		}finally{
			unlock();
		}
	}	
}

总结

提示:业务处理时间需要把控,一旦超过key的存活时间限制,锁就会被释放,看业务而定。
升级版本可借助lua脚本+redis
redission(帮我们实现了可重入的分布式锁,有个watchdag 机制)
保证强一致性可使用zookeeper的临时+有序节点,先在zookerper种创建一个固有持久节点,里面根据目前服务节点的个数,都注册临时有序节点,多个临时节点共同争抢同一把锁,释放锁删除节点。

你可能感兴趣的:(redis,java,redis)