redis分布式锁的实现

redis做分布式锁的实现在网上找到的资料要么是实现方式比较复杂(redis版本比较旧的情况下有必要),要么是释放锁的时候有坑,所以自己实现了一个。
支持 redis 2.6.12以上版本。
同时也是redis官网推荐的一种实现方式,可以到http://redis.io/commands/set 看官网说法

package com.extracme.evcard.redis;

import java.util.UUID;

import redis.clients.jedis.Jedis;

/**
*
* redis做分布式锁的实现
*
* @author wu yibo
*/
public class JedisLock {

private static final int ONE_SECOND = 1000;

public static final int DEFAULT_EXPIRY_TIME_MILLIS = 5 * ONE_SECOND;

private final Jedis jedis;

private final String lockKey;
private final int lockExpiryInMillis;
private final UUID lockUUID;
private boolean isLocked = false;


/**
* 生成锁对象
* @param jedis
* @param lockKey
*/
public JedisLock(Jedis jedis, String lockKey) {
this(jedis, lockKey, DEFAULT_EXPIRY_TIME_MILLIS);
}

/**
* 生成锁对象
* @param jedis
* @param lockKey
* @param expiryTimeMillis
*/
public JedisLock(Jedis jedis, String lockKey, int expiryTimeMillis) {
this(jedis, lockKey, expiryTimeMillis, UUID.randomUUID());
}

/**
* 生成锁对象
* @param jedis
* @param lockKey
* @param expiryTimeMillis
* @param uuid
*/
public JedisLock(Jedis jedis, String lockKey, int expiryTimeMillis, UUID uuid) {
this.jedis = jedis;
this.lockKey = lockKey;
this.lockExpiryInMillis = expiryTimeMillis;
this.lockUUID = uuid;;
}


public UUID getLockUUID() {
return lockUUID;
}


public String getLockKey() {
return lockKey;
}

/**
* 加锁
* @return
*
* @author wu yibo
*/
public synchronized boolean acquire() {
return acquire(jedis);
}

/**
* 加锁.
* 这里是用的是redis 的set指令来实现加锁,详情请看:http://redis.io/commands/set
* @param jedis
* @return
*
* @author wu yibo
*/
protected synchronized boolean acquire(Jedis jedis) {
//nx表示:Only set the key if it does not already exist.
//ps表示:Set the specified expire time, in milliseconds。超时时间的单位是毫秒
if(!isLocked) {
isLocked = jedis.set(this.lockKey, this.lockUUID.toString(), "nx", "px", this.lockExpiryInMillis) != null;
return isLocked;
}
return false;
}

/**
* 释放锁
*
* @author wu yibo
*/
public synchronized void release() {
release(jedis);
}

/**
* 释放锁
* @param jedis
*
* @author wu yibo
*/
protected synchronized void release(Jedis jedis) {
if(this.isLocked) {
//使用eval指令执行 Lua 脚本
//如果redis中该key对应的值已经变掉了,不再执行删除指令。防止偶然情况下线程执行时间过长,导致释放锁的时候把其他线程的锁释放掉
jedis.eval("if redis.call('get',KEYS[1]) == ARGV[1] then return redis.call('del',KEYS[1]) else return 0 end", 1, this.lockKey, this.lockUUID.toString());
}
isLocked = false;
}

/**
* 检查是否已经加锁
* @return
*
* @author wu yibo
*/
public synchronized boolean isLocked() {
return this.isLocked;
}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值