import redis.clients.jedis.Jedis;
import redis.clients.jedis.Transaction;
import java.util.UUID;
public class RedisLock {
private Jedis jedis;
private String lockKey;
private String lockValue;
private int expireTime;
private ThreadLocal lockThreadLocal;
private Thread watchdogThread;
public RedisLock(Jedis jedis, String lockKey, int expireTime) {
this.jedis = jedis;
this.lockKey = lockKey;
this.expireTime = expireTime;
this.lockThreadLocal = new ThreadLocal<>();
}
public boolean acquireLock() {
String value = UUID.randomUUID().toString();
String result = jedis.set(lockKey, value, "NX", "EX", expireTime);
if ("OK".equals(result)) {
lockValue = value;
lockThreadLocal.set(value);
startWatchdog();
return true;
}
return false;
}
public boolean releaseLock() {
String value = lockThreadLocal.get();
if (value != null) {
Transaction transaction = jedis.multi();
transaction.watch(lockKey);
if (value.equals(jedis.get(lockKey))) {
transaction.del(lockKey);
transaction.exec();
lockThreadLocal.remove();
stopWatchdog();
return true;
} else {
transaction.unwatch();
}
}
return false;
}
private void renewLock() {
while (lockThreadLocal.get() != null) {
// 续约锁的有效期
jedis.expire(lockKey, expireTime);
try {
Thread.sleep(expireTime * 1000 / 2); // 续约时间为锁有效期的一半
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
private void startWatchdog() {
watchdogThread = new Thread(this::renewLock);
watchdogThread.setDaemon(true);
watchdogThread.start();
}
private void stopWatchdog() {
if (watchdogThread != null) {
watchdogThread.interrupt();
}
}
}
使用示例:
java
import redis.clients.jedis.Jedis;
public class Main {
public static void main(String[] args) {
Jedis jedis = new Jedis(“localhost”, 6379);
RedisLock lock = new RedisLock(jedis, “my_resource”, 10);
if (lock.acquireLock()) {
try {
// 执行需要加锁的代码
} finally {
lock.releaseLock();
}
}
}
}