redis实现分布式锁

redis锁的注意事项:
1、(key,value)= (uuid,threadID)
uuid保证锁的唯一,threadID保证当前线程的锁不会被其他线程释放掉。
2、 防止死锁 ,所以使用setnx命令设置一个失效时间
3、 防止提前释放锁(当前线程没有执行完成,超时时间到了导致锁被删除) 开启一个守护线程来加时(执行续命操作)
守护线程的好处,任务执行完,守护线程自动删除。
4、 单点故障,使用redlock方案解决

为什么要使用分布式锁?
首先看synchronized的作用范围就是在一个JVM中有效,如果我在俩个系统中同时去秒杀一个商品,synchronized时不能控制并发的进行。
所以我们现在将锁放到一个能让所有的系统都能访问到公共的区域,然后设置一个布尔值,如果我在秒杀商品将布尔值设置为1(就是让别人等着,等我买完你们在来),当我买商品完毕,我将布尔值设置为0,下一个人再来买。基于这样的思想,我们就可以想到,公共区域数据库,redis缓存,zookeeper这些放在公共区域大家一起用的都可以用来实现分布式锁的。至于其他俩个我就不再这里说了。

redis上锁方法实现

redis实现锁的优点是redis中可以设置变量的超时时间。这样就不用我们去考虑死锁的问题,你可以在设置锁的时候顺带加一个超时时间,到时间之后自动失效。
ThreadLocal类很重要,它在这里就是起一个保证一把锁一把钥匙的。

    private ThreadLocal<String> threadLocal = new ThreadLocal<>();//线程安全问题,线程复用
/**
     * 上锁
     * @param key
     * @param timeout
     * @param unit
     * @return
     */
    public boolean tryLock(String key, long timeout, TimeUnit unit){

        String uuid = UUID.randomUUID().toString();//用uuid进行唯一标识当前锁
        threadLocal.set(uuid);
        boolean lock = stringRedisTemplate.opsForValue().setIfAbsent(key,uuid,timeout,unit);
        while (!lock){
            lock = stringRedisTemplate.opsForValue().setIfAbsent(key,uuid,timeout,unit);
            if (lock){
                break;
            }
        }
        return lock;
    }

解锁方法实现

 /**
     * 解锁
     * @param key
     */
    public void releaseLock(String key){
        if (threadLocal.get().equals(stringRedisTemplate.opsForValue().get(key))){

            stringRedisTemplate.delete(key);
        }
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值