使用 Redis 实现分布式锁,具体实现思想是使用 Redis 的 SETNX 命令尝试获取锁,如果 SETNX 返回 1,则表示成功获取锁;如果 SETNX 返回 0,则表示锁已经存在,需要判断锁是否已经过期,如果锁已经过期,则使用 GETSET 命令尝试获取锁。如果 GETSET 返回的值等于之前获取的值,则表示成功获取锁;如果 GETSET 返回的值不等于之前获取的值,则表示锁已经被其他进程获取。释放锁时,使用 DEL 命令删除锁的键。
import redis.clients.jedis.Jedis;
public class DistributedLock {
private static final String LOCK_KEY = "mylock";
private static final int LOCK_EXPIRE = 30000;
private Jedis jedis;
public DistributedLock(Jedis jedis) {
this.jedis = jedis;
}
public boolean acquire() {
long now = System.currentTimeMillis();
long expireTime = now + LOCK_EXPIRE + 1;
String expireStr = String.valueOf(expireTime);
if (jedis.setnx(LOCK_KEY, expireStr) == 1) {
return true;
}
String currentValueStr = jedis.get(LOCK_KEY);
if (currentValueStr != null && Long.parseLong(currentValueStr) < now) {
String oldValueStr = jedis.getSet(LOCK_KEY, expireStr);
if (oldValueStr != null && oldValueStr.equals(currentValueStr)) {
return true;
}
}
return false;
}
public void release() {
String currentValueStr = jedis.get(LOCK_KEY);
if (currentValueStr != null) {
jedis.del(LOCK_KEY);
}
}
public static void main(String[] args) {
Jedis jedis = new Jedis("localhost");
DistributedLock lock = new DistributedLock(jedis);
if (lock.acquire()) {
try {
} finally {
lock.release();
}
} else {
System.out.println("获取锁失败");
}
}
}