写一个关于lettuce redis的分布式锁,要防止被其他线程解锁
时间: 2023-07-13 14:09:36 浏览: 44
Lettuce是一个Redis的Java客户端,可以用它来实现分布式锁。下面是一个基于Lettuce的分布式锁实现方式:
```java
public class RedisDistributedLock {
private static final String LOCK_SUCCESS = "OK";
private static final String SET_IF_NOT_EXIST = "NX";
private static final String SET_WITH_EXPIRE_TIME = "PX";
private static final Long RELEASE_SUCCESS = 1L;
private static final Long DEFAULT_TIMEOUT = 5000L;
private RedisClient redisClient;
public RedisDistributedLock(String host, int port) {
redisClient = RedisClient.create("redis://" + host + ":" + port);
}
/**
* 获取锁
* @param lockKey 锁的key
* @param requestId 请求标识,用来防止其他线程解锁
* @param expireTime 锁的过期时间
* @return 是否获取成功
*/
public boolean tryLock(String lockKey, String requestId, long expireTime) {
StatefulRedisConnection<String, String> connection = null;
RedisCommands<String, String> redisCommands = null;
try {
connection = redisClient.connect();
redisCommands = connection.sync();
String result = redisCommands.set(lockKey, requestId, SET_IF_NOT_EXIST, SET_WITH_EXPIRE_TIME, expireTime);
return LOCK_SUCCESS.equals(result);
} catch (Exception e) {
e.printStackTrace();
} finally {
if (connection != null) {
connection.close();
}
}
return false;
}
/**
* 释放锁
* @param lockKey 锁的key
* @param requestId 请求标识,用来防止其他线程解锁
* @return 是否释放成功
*/
public boolean unlock(String lockKey, String requestId) {
StatefulRedisConnection<String, String> connection = null;
RedisCommands<String, String> redisCommands = null;
try {
connection = redisClient.connect();
redisCommands = connection.sync();
String lockValue = redisCommands.get(lockKey);
if (requestId.equals(lockValue)) {
Long result = redisCommands.del(lockKey);
return RELEASE_SUCCESS.equals(result);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
if (connection != null) {
connection.close();
}
}
return false;
}
}
```
上述代码中,我们通过set命令来获取锁,使用了SET_IF_NOT_EXIST和SET_WITH_EXPIRE_TIME两个参数来保证了锁的互斥性和过期时间。释放锁时,我们通过get命令获取当前锁的值,如果等于请求标识,则使用del命令删除锁。
需要注意的是,我们在获取锁和释放锁的时候都需要使用请求标识来防止被其他线程解锁。同时,我们还可以设置默认的超时时间,在获取锁时如果超时则返回false,避免长时间等待。