写一个关于lettuce redis的分布式锁的工具类
时间: 2023-10-11 13:05:30 浏览: 142
redis分布式锁工具类
以下是一个基于 Lettuce Redis 的分布式锁的工具类实现:
```java
import io.lettuce.core.RedisClient;
import io.lettuce.core.RedisConnectionException;
import io.lettuce.core.api.StatefulRedisConnection;
import io.lettuce.core.api.sync.RedisCommands;
import io.lettuce.core.cluster.RedisClusterClient;
import io.lettuce.core.cluster.RedisClusterConnectionException;
import io.lettuce.core.cluster.api.StatefulRedisClusterConnection;
import io.lettuce.core.cluster.api.sync.RedisAdvancedClusterCommands;
import java.util.concurrent.TimeUnit;
public class RedisLock {
private static final String LOCK_PREFIX = "lock:";
private static final long DEFAULT_EXPIRE_TIME = 60; // 默认锁的过期时间为 60 秒
private RedisCommands<String, String> redisCommands;
private RedisAdvancedClusterCommands<String, String> redisClusterCommands;
/**
* 初始化 Redis 连接
*
* @param redisHost Redis 服务器地址
* @param redisPort Redis 服务器端口
* @param redisPassword Redis 服务器密码,如果没有设置则传入 null
* @param useCluster 是否使用 Redis Cluster
* @throws RedisConnectionException Redis 连接异常
* @throws RedisClusterConnectionException Redis Cluster 连接异常
*/
public RedisLock(String redisHost, int redisPort, String redisPassword, boolean useCluster)
throws RedisConnectionException, RedisClusterConnectionException {
if (useCluster) {
RedisClusterClient redisClusterClient = RedisClusterClient.create(
"redis://" + redisHost + ":" + redisPort);
if (redisPassword != null) {
redisClusterClient.setOptions(
redisClusterClient.getOptions().setPassword(redisPassword));
}
StatefulRedisClusterConnection<String, String> redisClusterConnection =
redisClusterClient.connect();
redisClusterCommands = redisClusterConnection.sync();
} else {
RedisClient redisClient = RedisClient.create(
"redis://" + redisHost + ":" + redisPort);
if (redisPassword != null) {
redisClient.setOptions(redisClient.getOptions().setPassword(redisPassword));
}
StatefulRedisConnection<String, String> redisConnection = redisClient.connect();
redisCommands = redisConnection.sync();
}
}
/**
* 尝试获取分布式锁
*
* @param lockName 锁名称
* @param expireTime 锁的过期时间,单位为秒
* @return 是否获取成功
*/
public boolean tryLock(String lockName, long expireTime) {
String lockKey = LOCK_PREFIX + lockName;
long start = System.currentTimeMillis();
while (true) {
if (redisCommands != null) {
String result = redisCommands.set(lockKey, "", "NX", "EX", expireTime);
if ("OK".equals(result)) {
return true;
}
} else if (redisClusterCommands != null) {
String result = redisClusterCommands.set(lockKey, "", "NX", "EX", expireTime);
if ("OK".equals(result)) {
return true;
}
}
if (System.currentTimeMillis() - start > (expireTime - 1) * 1000) {
break;
}
try {
TimeUnit.MILLISECONDS.sleep(100);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
return false;
}
/**
* 尝试获取分布式锁,使用默认的过期时间
*
* @param lockName 锁名称
* @return 是否获取成功
*/
public boolean tryLock(String lockName) {
return tryLock(lockName, DEFAULT_EXPIRE_TIME);
}
/**
* 释放分布式锁
*
* @param lockName 锁名称
*/
public void releaseLock(String lockName) {
String lockKey = LOCK_PREFIX + lockName;
if (redisCommands != null) {
redisCommands.del(lockKey);
} else if (redisClusterCommands != null) {
redisClusterCommands.del(lockKey);
}
}
}
```
使用示例:
```java
public class RedisLockTest {
public static void main(String[] args) throws Exception {
RedisLock redisLock = new RedisLock("localhost", 6379, null, false);
boolean locked = redisLock.tryLock("mylock");
if (locked) {
try {
// 执行业务逻辑
} finally {
redisLock.releaseLock("mylock");
}
} else {
System.out.println("获取锁失败!");
}
}
}
```
上述代码实现了一个基于 Lettuce Redis 的分布式锁的工具类,可以通过 tryLock 方法尝试获取锁,通过 releaseLock 方法释放锁。可以根据自己的实际需求来设置锁的过期时间。
阅读全文