一、复习
场景模拟
初始化
在获取锁的时候,会初始化一些参数,例如commandExecutor leaseTime uuid
● commandExecutor 命令执行器
● leaseTime 持有锁的最大时间,租期
● uuid 客户端的唯一标识
第一次加锁
- 设置获取到锁的主体,使用线程id作为标识
- 当未设置leaseTime的时候,也就是代表的锁可以无限持有时间
- 判断redis中是否已经存在了这个锁
- 第一次加锁肯定不存在,递增一个lockName为key的hash数据结构里面的一个key为uuid:threadId的元素
{
"lockName": {
"uuid:threadId": 1
}
}
- 给设置这个redis key设置一个过期时间 leaseTime,返回一个null
- 此时,就表明了客户端已经加锁成功了
- 收到监听加锁结果后,判断条件是ttl == null就表示这个客户端加锁成功
- 如果锁是有最大持有时长的,就会直接结束整个流程
- 如果是没有最大持有时长,会启动一个leaseTime/3 后执行的任务,任务会将锁的过期时间重新给设置为leaseTime,这个机制也被称之为watchdog
- 同时,本地还会维护一个watchdog需要监听的map,也就是每一个加锁成功且需要watchdog去设置过期时间的锁都会被记录在map中
{
"uuid:lockName": {
"timeout": timeout object,
"threadIds":