分布式锁的本质:就是在所有进程都能访问到的一个地方(如数据库、zookeeper、Redis),设置一个锁资源,让这些进程都来竞争锁资源。通常对于分布式锁,会要求响应快、性能高、与业务无关。
Redis实现分布式锁:
public boolean tryLock(RedisConnect conn){
if(conn.SETNX("mykey", "1")==1){
return true;
}else{
return false;
}
}
public boolean tryLock(RedisConnect conn){
if(conn.SETNX("mykey", "1")==1){
// 给锁设置过期时间
conn.EXPIER("mykey", 1000);
return true;
}else{
return false;
}
}
public boolean tryLock(RedisConnect conn){
long nowTime = System.currentTimeMillis();
long expireTime = nowTime+1000;
if(conn.SETNX("mykey", "expireTime)==1){
// 给锁设置过期时间
// conn.EXPIER("mykey", 1000);
return true;
}else{
// SETNX获取锁失败时,拿过期时间跟当前时间比对,如果是过期锁,就先删除锁,再重新上锁。
long val = conn.get("mykey");
if(val!=null&&val<nowTime){
// 此处直接覆盖锁
conn.SET("mykey", expireTime);
return true;
}
return false;
}
}
public boolean tryLock(RedisConnect conn){
// 将锁的内容设置为过期时间(客户端时间+过期时长)
long nowTime = System.currentTimeMillis();
long expireTime = nowTime+1000;
if(conn.SETNX("mykey", "expireTime)==1){
conn.EXPIER("mykey", 1000);
return true;
}else{
// SETNX失败后,获取锁上面的时间戳
long oldVal = conn.get("mykey");
if(oldVal!=null&&oldVal<nowTime){
// 然后用GETSET,将自己的过期时间更新上去,并获取旧值
long currentVal = conn.GETSET("mykey", expireTime);
if(oldVal==currentVal){
conn.EXPIRE("mykey", 1000);
return true;
}
// 如果这个旧值,跟之前获得的时间戳是不一样的,就表示这个锁已经被其他进程占用了,自己就要放弃竞争锁。
return false;
}
return false;
}
}
原文:https://www.cnblogs.com/pangqianjin/p/14616932.html