使用java代码做一个功能齐全的redis分布式锁
时间: 2023-10-11 09:07:03 浏览: 104
redis 分布式锁java 实现
以下是一个基本的Redis分布式锁的Java实现。它包括获取锁、释放锁、自动续期、可重入等功能。可以根据具体需求进行修改和优化。
```java
import redis.clients.jedis.Jedis;
import redis.clients.jedis.params.SetParams;
public class RedisDistributedLock {
private final Jedis jedis;
private final String lockKey;
private final String lockValue;
private final int expireTime;
private final long retryInterval;
private final int maxRetryTimes;
private final ThreadLocal<Integer> reentrantCount;
public RedisDistributedLock(Jedis jedis, String lockKey, String lockValue, int expireTime, long retryInterval, int maxRetryTimes) {
this.jedis = jedis;
this.lockKey = lockKey;
this.lockValue = lockValue;
this.expireTime = expireTime;
this.retryInterval = retryInterval;
this.maxRetryTimes = maxRetryTimes;
this.reentrantCount = new ThreadLocal<>();
this.reentrantCount.set(0);
}
/**
* 获取锁
*
* @return true:获取锁成功;false:获取锁失败
*/
public boolean lock() throws InterruptedException {
int retryTimes = 0;
while (retryTimes < maxRetryTimes) {
SetParams params = new SetParams();
params.nx().ex(expireTime);
String result = jedis.set(lockKey, lockValue, params);
if ("OK".equals(result)) {
return true;
}
retryTimes++;
Thread.sleep(retryInterval);
}
return false;
}
/**
* 释放锁
*/
public void unlock() {
int count = reentrantCount.get();
if (count > 0) {
reentrantCount.set(count - 1);
return;
}
if (lockValue.equals(jedis.get(lockKey))) {
jedis.del(lockKey);
}
}
/**
* 自动续期
*/
public void renew() {
jedis.expire(lockKey, expireTime);
}
/**
* 可重入锁
*
* @return true:获取锁成功;false:获取锁失败
*/
public boolean reentrantLock() {
int count = reentrantCount.get();
if (count > 0) {
reentrantCount.set(count + 1);
return true;
}
if (lockValue.equals(jedis.get(lockKey))) {
reentrantCount.set(1);
return true;
}
return false;
}
}
```
使用示例:
```java
public class Main {
public static void main(String[] args) throws InterruptedException {
Jedis jedis = new Jedis("localhost", 6379);
RedisDistributedLock lock = new RedisDistributedLock(jedis, "my_lock", "my_value", 10, 1000, 3);
try {
if (lock.lock()) {
// 获取锁成功,执行业务逻辑
System.out.println("Got the lock, do something...");
Thread.sleep(5000);
} else {
// 获取锁失败,处理异常情况
System.out.println("Failed to get the lock");
}
} finally {
lock.unlock();
}
}
}
```
注意事项:
- RedisDistributedLock类的构造函数需要传入Jedis对象,因此需要先导入jedis依赖。
- 为了防止误删其他线程的锁,lockValue应该是一个随机生成的字符串,确保每个线程都有自己的标识。
- 自动续期和可重入锁需要在业务逻辑中显式调用,否则会因为过期或者重入次数不匹配而导致锁失效。
阅读全文