type
status
date
slug
summary
tags
category
icon
password
原文
Redisson 支持多种 Redis 部署方式。每种部署方式的不同对应加锁和解锁的策略有所不一样。
可重入锁
RedissonLock 最常用的分布式锁。
常用的加锁方法
public void lock()
无返回值,默认过期时间30秒,可续约
public void lock(long leaseTime, TimeUnit unit)
可设置 key 的过期时间(
leaseTime
)public boolean tryLock()
带返回值 默认过期时间,可续约
public boolean tryLock(long waitTime, long leaseTime, TimeUnit unit)
带返回值的加锁方法,可设置过期时间,等待时间。
waitTime 相当于一个计数器,如果在该时间内未能获取到锁则返回 false
加锁流程

lock操作
RedissonLock
lock执行 Lua 脚本源码
- 无论是 tryLock 开头的方法还是 lock 方法最后执行加锁操作底层的逻辑都是以发送Lua 脚本交给 Redis 执行。
- 锁是 hash结构:执行完该命令,Redis 会创建一个key为加锁时定义的hash结构。内容KV存储,key 为 {nodeId}:{threadId},value 为当前加锁线程的重入计数器。
hash结构是为了支持锁的重入(同个线程多次获取同一把锁)。在Redisson 中 支持当前线程多次 lock操作。
早期很多自定义实现的锁都采用Redis的String来实现,如果要实现重入在 value 存threadId,如果存重入次数就需要另外一个 key来做计数器,但是这样也会有问题,因为保证两个key的操作原子性了。如果真是这样的设计,就需要自己编写 Lua脚本,来保证两个 key 在 Redis中操作的原子性。这样的设计远没有 hash结构来的方便。

为什么要可重入性
锁的重入主要为了防止死锁。
过期时间的设置
key的设置过期时间(主动设置非默认)没有业务执行的时间长,则 unlock 操作时 发现key 已经过期会抛出异常。
主动设置过期时间,锁是不会自动续期的。
续期操作
加锁时key没有设置过期时间,RedissonLock 会给该 key 设置一个默认过期时期(30 秒)。默认的过期时间可以通过配置修改。
如果 key设置了过期时间,则不会有自动续期。
需要续期的key包装成 Task (
RenewalTask
)形式加入到时间轮中去执行,延时时间是默认的过期时间的三分之一。如果未设置 key的过期时间,Redisson 设置了 30 秒,加入到时间轮中,每隔10 秒时间进行续期操作。
unlock 操作
解锁操作不是直接删除 key。
加锁和解锁的线程id要保持一样。
解锁操作时如果与加锁时线程 id不一致,会抛出异常。
每一次 unlock 相当于将锁的冲入计数器减1,如果计数器等于 0,则删除锁,并发布解锁消息(
LockPubSub.UNLOCK_MESSAGE
)。- Author:newrain-zh
- URL:https://alex.sh.cn/article/redisson-lock
- Copyright:All articles in this blog, except for special statements, adopt BY-NC-SA agreement. Please indicate the source!