redis实现分布式锁

1、利用redis的SETNX命令来实现分布式锁

     SETNX key value 当前仅当key不存在时,为key设置value值,value是随机生成的UUID,返回1成功,如果key已经存在则返回0失败

      以下加锁代码:

    public String acquireLock(Jedis conn, String lockName) {
        return acquireLock(conn, lockName, 10000);
    }
    public String acquireLock(Jedis conn, String lockName, long acquireTimeout){
        String identifier = UUID.randomUUID().toString();
        //给定acquireTimeout,如果锁获取失败,那么会不断的重试,知道成功获取锁或者超过给定的是时限为止
        long end = System.currentTimeMillis() + acquireTimeout;
        while (System.currentTimeMillis() < end){
            if (conn.setnx("lock:" + lockName, identifier) == 1){
                return identifier;
            }

            try {
                Thread.sleep(1);
            }catch(InterruptedException ie){
                Thread.currentThread().interrupt();
            }
        }

        return null;
    }

如果获取锁后,没有超时设置,将导致锁一直处于被获取的状态,以下为锁设置超时时间:

   public String acquireLockWithTimeout(
        Jedis conn, String lockName, long acquireTimeout, long lockTimeout)
    {
        String identifier = UUID.randomUUID().toString();
        String lockKey = "lock:" + lockName;
         //设置超时时间,获取锁成功后,超时释放锁,不会造成死锁
        int lockExpire = (int)(lockTimeout / 1000);

        long end = System.currentTimeMillis() + acquireTimeout;
        while (System.currentTimeMillis() < end) {
            if (conn.setnx(lockKey, identifier) == 1){
                conn.expire(lockKey, lockExpire);
                return identifier;
            }
            //如果该锁没有设置超时时间,这加上超时时间
            if (conn.ttl(lockKey) == -1) {
                conn.expire(lockKey, lockExpire);
            }

            try {
                Thread.sleep(1);
            }catch(InterruptedException ie){
                Thread.currentThread().interrupt();
            }
        }

        // null indicates that the lock was not acquired
        return null;
    }

最后释放锁:

   //不断的重试,直到锁释删除掉
    public boolean releaseLock(Jedis conn, String lockName, String identifier) {
        String lockKey = "lock:" + lockName;
        while (true){
            conn.watch(lockKey);
            if (identifier.equals(conn.get(lockKey))){
                Transaction trans = conn.multi();
                trans.del(lockKey);
                List<Object> results = trans.exec();
                if (results == null){
                    continue;
                }
                return true;
            }
            conn.unwatch();
            break;
        }

        return false;
    }

以上是redis分布式锁的实现方式,代码摘自《redis实战》,不喜勿喷

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值