前面已经分析了可重入锁的加锁,本节来看一下是怎么释放锁的。
主动释放
当线程完成一系列操作之后,我们都需要主动去释放锁,调用RedissonLock
实例的unlock()
方法即可以释放锁,查看源码可知最终调用到了 RedissonLock
中的 unlockInnerAsync(long threadId)
这个方法,该方法中用到了当前线程的id。
1 | protected RFuture<Boolean> unlockInnerAsync(long threadId) { |
分析一下方法里面用到的 lua 脚本。
- 如果锁不存在,直接返回 null;
- 如果锁存在,则对锁的重入次数 -1;
- 剩余重入次数大于 0,重新设置过期时间,返回 0;
- 剩余重入次数不大于 0,删除 redis key 并发布消息,返回 1;
主动释放锁这块考虑的不仅仅是对 key 进行处理,因为可能存在重入锁,所以会先对 key 对应的 hash 表中的 value 进行递减,相当于减去重入次数。
自动释放
和主动释放相比,自动释放的情况就更加简单了。比如下面两种情形:
- 当服务宕机时,看门狗不再看门,那么最多 30s 之后锁被自动释放;
- 当设置锁的时间,超时自动释放。