Redis--12--1--分布式锁---java
在Java中使用Redis实现分布式锁通常会借助Redis的SETNX
命令(或在Redis 2.6.12以上版本中使用SET key value EX max-lock-time NX
命令),以下是一个简单的示例:
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() {
// 删除锁,注意这里并未做原子性检查,可以考虑使用Lua脚本来保证原子性
jedis.del(lockKey);
}
}
使用方法:
Jedis jedis = new Jedis("localhost", 6379);
RedisDistributedLock lock = new RedisDistributedLock(jedis, "my_lock", 1000);
if (lock.lock()) {
try {
// 业务逻辑
} finally {
lock.unlock();
}
}
这个示例中的锁实现有一些问题,比如没有考虑解锁时的原子性,以及没有考虑Redis的主从同步延迟导致的锁失效问题。在实际应用中,推荐使用更成熟的Redlock算法或者Redisson这样的库来实现分布式锁。
评论已关闭