以下是一个使用Jedis库实现基于Redis的分布式锁的简单示例:
import redis.clients.jedis.Jedis;
public class RedisDistributedLock {
private Jedis jedis;
private String lockKey; // 锁的键值
private int expireTime; // 锁的超时时间
public RedisDistributedLock(Jedis jedis, String lockKey, int expireTime) {
this.jedis = jedis;
this.lockKey = lockKey;
this.expireTime = expireTime;
}
public boolean lock() {
long expires = System.currentTimeMillis() + expireTime + 1;
String expiresStr = String.valueOf(expires); // 锁到期时间
if (jedis.setnx(lockKey, expiresStr) == 1) {
// 获取锁成功
jedis.expire(lockKey, expireTime); // 设置锁的过期时间
return true;
}
String currentValueStr = jedis.get(lockKey); // Redis里面的时间
if (currentValueStr != null && Long.parseLong(currentValueStr) < System.currentTimeMillis()) {
String oldValueStr = jedis.getSet(lockKey, expiresStr);
if (oldValueStr != null && oldValueStr.equals(currentValueStr)) {
// 锁已过期,获取锁成功
jedis.expire(lockKey, expireTime); // 设置锁的过期时间
return true;
}
}
return false; // 获取锁失败
}
public void unlock() {
// 确保是该线程获得的锁才能被释放
String currentValueStr = jedis.get(lockKey);
if (currentValueStr != null && Long.parseLong(currentValueStr) > System.currentTimeMillis()) {
jedis.del(lockKey); // 删除锁
}
}
}
使用方法:
Jedis jedis = new Jedis("localhost", 6379);
RedisDistributedLock lock = new RedisDistributedLock(jedis, "my_lock", 1000);
try {
if (lock.lock()) {
// 业务逻辑
} else {
// 获取锁失败,执行其他逻辑或者等待重试
}
} finally {
lock.unlock(); // 释放锁
}
这个示例中的lock
方法尝试获取锁,如果获取成功,则设置锁的过期时间;如果获取失败,则检查锁是否已过期,如果已过期,则尝试重新获取锁。unlock
方法则确保只有获得锁的线程才能释放锁,防止释放其他线程持有的锁。