redis分布式锁

public static boolean lock(String preCode, int expire) throws InterruptedException {
		JedisCluster jedisCluster = JedisClusterUtil.getInstance().getJedisCluster();
		Long beginTime = System.currentTimeMillis();
		long expires = System.currentTimeMillis() + expire + 1;
		do{
			if(jedisCluster.setnx(preCode, String.valueOf(expires))==1){
				return true;
			}else {
				String currentValueStr = jedisCluster.get(preCode); //redis里的时间
				if (currentValueStr != null && Long.parseLong(currentValueStr) < System.currentTimeMillis()) {
					String oldValueStr = jedisCluster.getSet(preCode, String.valueOf(expires));
					//获取上一个锁到期时间,并设置现在的锁到期时间,
					//只有一个线程才能获取上一个线上的设置时间,因为jedis.getSet是同步的
					if (oldValueStr != null && oldValueStr.equals(currentValueStr)) {
						return true;
					}
				}
				Thread.sleep(100);
			}
		}while((System.currentTimeMillis() - beginTime) < expire);

		return false;
	}

	public static void unLock(String preCode) {
		JedisCluster jedisCluster = JedisClusterUtil.getInstance().getJedisCluster();
		jedisCluster.del(preCode);
	}

以上实现需要要求所有机器的时钟一致。

以下可以通过lua脚本的方式

// “自旋”,等待锁
 static boolean lock(String key, String value,long exprie){
        // 申请锁,只有当“key”不存在时才能申请成功,返回“OK",锁的过期时间设置为exprie秒
        //String result = jedis.set(key, value, NX, PX, exprie);
       JedisCluster jedisCluster = JedisClusterUtil.getInstance().getJedisCluster();
        String result = (String) jedisCluster.eval("return redis.call('set', KEYS[1],ARGV[1],'nx', 'ex', ARGV[2]) ", Collections.singletonList(key),   Arrays.asList(value, exprie+""));
        if ("OK".equals(result))
        {
            return true;
        }
        return false;

    }


    // Lua脚本,用于校验并释放锁
    static boolean unlock(String key, String value){
        String script = "if redis.call('get', KEYS[1]) == ARGV[1] then return redis.call('del', KEYS[1]) else return 0 end";

        // 执行Lua脚本,校验并释放锁
        JedisCluster jedisCluster = JedisClusterUtil.getInstance().getJedisCluster();
        return 1L==jedisCluster.eval(script, Collections.singletonList(key),
                Collections.singletonList(value));
    }

 

jar依赖如下

  <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
        </dependency>

        <dependency>
            <groupId>redis.clients</groupId>
            <artifactId>jedis</artifactId>
        </dependency>

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值