原创文章首发微信公众号「后端技术学堂」转载请先与我联系,点文末链接「了解更多」
![2b823fc0ecaf196c8cf07f202f91cd11.png](https://img-blog.csdnimg.cn/img_convert/2b823fc0ecaf196c8cf07f202f91cd11.png)
今天就来说说高并发编程中redis分布式锁实现,这里罗列出3种redis实现的分布式锁,并分别对比说明各自特点。
Redis单实例分布式锁
实现一:SETNX实现的分布式锁
setnx用法参考redis官方文档
语法
SETNX key value
将key设置值为value,如果key不存在,这种情况下等同SET命令。当key存在时,什么也不做。SETNX是”SET if Not eXists”的简写。
返回值:
- 1 设置key成功
- 0 设置key失败
加锁步骤
- SETNX lock.foo 如果客户端获得锁,SETNX返回1,加锁成功。如果SETNX返回0,那么该键已经被其他的客户端锁定。
- 接上一步,SETNX返回0加锁失败,此时,调用GET lock.foo获取时间戳检查该锁是否已经过期:
- 若旧的时间戳已过期,则表示加锁成功。
- 若旧的时间戳还未过期(说明被其他客户端抢去并设置了时间戳),代表加锁失败,需要等待重试。
- 如果没有过期,则休眠一会重试。
- 如果已经过期,则可以获取该锁。具体的:调用GETSET lock.foo 基于当前时间设置新的过期时间。注意: 这里设置的时候因为在SETNX与GETSET之间有个窗口期,在这期间锁可能已被其他客户端抢去,所以这里需要判断GETSET的返回值,它的返回值是SET之前旧的时间戳:
解锁步骤
解锁相对简单,只需GET lock.foo时间戳,判断是否过期,过期就调用删除DEL lock.foo
实现二:SET实现的分布式锁
set用法参考官方文档
语法
SET key value [EX seconds|PX milliseconds] [NX|XX]
将键key设定为指定的“字符串”值。如果 key