分布式锁一般有三种实现方式
- 数据库乐观锁。
- 基于Redis的分布式锁。
- 基于ZooKeeper的分布式锁。
一、Redis实现分布式锁
- 通过setnx,不存在key则插入成功,存在key则不插入
- 且加上过期时间,防止释放锁失败一直死锁
- 插入和设置过期时间是原子性操作
- 释放锁,只有当前持有改锁的客户端能够释放锁。通过Lua脚本执行,如果redis value相同才删除key。如果不是原子性操作,A客户端的value=redisValue,刚好过期,B客户端过来访问获取到锁,此时A客户端执行删除key释放锁。可能误释放B的锁
/**
* 获取分布式锁, 且锁加上过期时间
* 单个redis服务器, 已有key存在, 则函数不会调用成功。只有一个客户端能持有key, 通过setNx + 过期时间实现锁
* @param key
* @param value
* @param expireTime 秒
* @return
*/
public static boolean getDistributedLock(RedisService redisService, String key, String value, int expireTime) {
boolean res = redisService.setNxExpire(key, value, expireTime);
logger.info(String.format("key:%s, 获取锁结果:%s", key, res));
return res;
}
public boolean setNxExpire(String key, String value, int seconds) {
Jedis jedis = null;
try {
jedis = getJedis(jedisPool);
String result = jedis.set(key, value, "NX", "EX", seconds);
if ("OK".equals(result)) {
return true;
} else {
return false;
}
} catch (Exception e) {
returnBrokenResource(jedis);
} finally {
returnResource(jedis);
}
return false;
}
/**
* 释放分布式锁, 只有value相同时才能释放
* @param key
* @param value
* @return
*/
public static boolean releaseDistributedLock(RedisService redisService, String key, String value) {
String script = "if redis.call('get', KEYS[1]) == ARGV[1] then return redis.call('del', KEYS[1]) else return 0 end";
Object result = redisService.eval(script, key, value);
if (null == result) {
return false;
}
if (Long.valueOf(1).equals(result)) {
return true;
} else {
return false;
}
}
@Override
public Object eval(String script, String key, String value) {
Jedis jedis = null;
try {
jedis = getJedis(jedisPool);
return jedis.eval(script, Collections.singletonList(key), Collections.singletonList(value));
} catch (Exception e) {
returnBrokenResource(jedis);
} finally {
returnResource(jedis);
}
return null;
}
使用示例

二、乐观锁和悲观锁
- 乐观锁:每次去拿数据的时候都认为别人不会修改,所以不会上锁,但是在更新的时候会判断一下在此期间别人有没有去更新这个数据,CAS算法实现。
- 悲观锁:总是假设最坏的情况,每次去拿数据的时候都认为别人会修改,所以每次在拿数据的时候都会上锁,这样别人想拿这个数据就会阻塞直到它拿到锁。
- CAS存在ABA问题
参考内容
- https://www.jb51.net/article/169108.htm
172万+

被折叠的 条评论
为什么被折叠?



