基于redis实现的简单分布式锁

单实例的分布式锁:

加锁-设计思路是通过setnx命令(只有key不存中才可以加锁)给key设置一个value值(用UUID/雪花算法)并设置一个有效时间(避免死锁),注意value值必须是唯一的字符串(后期作为解锁条件之一的判断依据(自动失效也是一种))

在加锁的时候还需要设置一个加锁的超时时间,若超过这个时间则放弃获取锁

释放锁的时候通过UUID判断该线程的锁是不是该锁,若不是则放弃解锁,否则执行delete

核心代码

import redis.clients.jedis.Jedis;
import util.JedisUtil;
import java.util.UUID;
public class LockUtil {
    public String LockTimeout(long lockTime, int lockExpire, String lockName) {
        Jedis jedis = null;
        try {
            jedis = new JedisUtil().getInstance();
            String value;
            if (lockExpire <= 0 || lockTime <= 0) {
                return null;
            }
            value = UUID.randomUUID().toString();
            //参试获取锁
            Long islock = jedis.setnx(LockConst.LOCK_NAME_PRIFIX + lockName, value);
            if (islock > 0) {
                //成功获取锁后,加有效时间防止死锁
                jedis.expire(LockConst.LOCK_NAME_PRIFIX + lockName, lockExpire);
                System.out.println("加锁成功");
                return value;
            } else {
                //获取锁失败后,指定时间内重试
                while (System.currentTimeMillis() < (lockTime + lockExpire)) {
                    // System.out.println("在尝试获取锁!!");
                    islock = jedis.setnx(LockConst.LOCK_NAME_PRIFIX + lockName, value.toString());
                    if (islock > 0) {
                        jedis.expire(LockConst.LOCK_NAME_PRIFIX + lockName, lockExpire);
                        System.out.println("在尝试,加锁成功");
                        return value;
                    }
                }
                return null;
            }
        } finally {
            if (jedis != null) {
                jedis.close();
            }
        }
    }
    public boolean unLock(String locakName, String value) {
        Jedis jedis = new JedisUtil().getInstance();
        if (value == null || locakName == null) {
            return false;
        }
        try {
            //value只根据解锁一致的则解锁
            String val = jedis.get(LockConst.LOCK_NAME_PRIFIX + locakName);
            if (value.equals(val)) {
                jedis.del(LockConst.LOCK_NAME_PRIFIX + locakName);
                System.out.println("unlock成功");
                return true;
            }
            System.out.println("unlock失败,该锁不是该线程上的");
            return false;
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (jedis != null)
                jedis.close();
        }
        return false;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值