@Overridepublic void unlock() {//解锁成功返回trueBoolean opStatus = get(unlockInnerAsync(Thread.currentThread().getId()));if (opStatus == null) {throw new IllegalMonitorStateException("attempt to unlock lock, not locked by current thread by node id: "+ id + " thread-id: " + Thread.currentThread().getId());}if (opStatus) {//取消定时任务cancelExpirationRenewal();}}

第一步:发布解锁消息删除key

protected RFuture<Boolean> unlockInnerAsync(long threadId) {return commandExecutor.evalWriteAsync(getName(), LongCodec.INSTANCE, RedisCommands.EVAL_BOOLEAN,"if (redis.call('exists', KEYS[1]) == 0) then " +"redis.call('publish', KEYS[2], ARGV[1]); " +"return 1; " +"end;" +"if (redis.call('hexists', KEYS[1], ARGV[3]) == 0) then " +"return nil;" +"end; " +"local counter = redis.call('hincrby', KEYS[1], ARGV[3], -1); " +"if (counter > 0) then " +"redis.call('pexpire', KEYS[1], ARGV[2]); " +"return 0; " +"else " +"redis.call('del', KEYS[1]); " +"redis.call('publish', KEYS[2], ARGV[1]); " +"return 1; "+"end; " +"return nil;",Arrays.<Object>asList(getName(), getChannelName()), LockPubSub.unlockMessage, internalLockLeaseTime, getLockName(threadId));}

调用lua脚本,exists命令:若 key 存在返回 1 ,否则返回 0 。

publish 发布unlockMessage消息

hexists 如果哈希表含有给定字段,返回 1 。 如果哈希表不含有给定字段,或 key 不存在,返回 0 。

hincrby Redis Hincrby 命令用于为哈希表中的字段值加上指定增量值,此处是-1即减1,因为存在重入锁问题,N次上锁需要N次解锁

del 删除key

第二步:取消定时任务

void cancelExpirationRenewal() {//移除过期时间重置Map中的数据 并返回对应valueTimeout task = expirationRenewalMap.remove(getEntryName());if (task != null) {//取消任务task.cancel();}
}
private static final ConcurrentMap<String, Timeout> expirationRenewalMap = PlatformDependent.newConcurrentHashMap();

调用lock(),tryLock()无参方法会生成一个定时任务,手动unlock的时候会取消任务

Redis源码分析之unlock相关推荐

  1. Redis源码分析:基础概念介绍与启动概述

    Redis源码分析 基于Redis-5.0.4版本,进行基础的源码分析,主要就是分析一些平常使用过程中的内容.仅作为相关内容的学习记录,有关Redis源码学习阅读比较广泛的便是<Redis设计与 ...

  2. Redis源码分析(一)redis.c //redis-server.c

    Redis源码分析(一)redis.c //redis-server.c 入口函数 int main() 4450 int main(int argc, char **argv) {4451 init ...

  3. redis源码分析 -- cs结构之服务器

    服务器与客户端是如何交互的 redis客户端向服务器发送命令请求,服务器接收到客户端发送的命令请求之后,读取解析命令,并执行命令,同时将命令执行结果返回给客户端. 客户端与服务器交互的代码流程如下图所 ...

  4. 10年大厂程序员是如何高效学习使用redis的丨redis源码分析丨redis存储原理

    10年大厂程序员是怎么学习使用redis的 1. redis存储原理分析 2. redis源码学习分享 3. redis跳表和B+树详细对比分析 视频讲解如下,点击观看: 10年大厂程序员是如何高效学 ...

  5. Redis源码分析(一)--Redis结构解析

    从今天起,本人将会展开对Redis源码的学习,Redis的代码规模比较小,非常适合学习,是一份非常不错的学习资料,数了一下大概100个文件左右的样子,用的是C语言写的.希望最终能把他啃完吧,C语言好久 ...

  6. Redis 源码分析之故障转移

    在 Redis cluster 中故障转移是个很重要的功能,下面就从故障发现到故障转移整个流程做一下详细分析. 故障检测 PFAIL 标记 集群中每个节点都会定期向其他节点发送 PING 消息,以此来 ...

  7. Redis源码分析之PSYNC同步

    Redis master-slave 同步源码分析 (1)slave 流程分析 (2)master 流程分析 Slave 分析 当Redis 启动后,会每隔 1s 调用 replicationCron ...

  8. Redis源码分析 —— 发布与订阅

    前言 通过阅读Redis源码,配合GDB和抓包等调试手段,分析Redis发布订阅的实现原理,思考相关问题. 源码版本:Redis 6.0.10 思考问题 发布订阅基本概念介绍 订阅频道 -- SUBS ...

  9. Redis源码分析之工具类util

    在redis源码中的辅助工具类中,主要包括大小端转换.SHA算法以及util.h中对应的算法. 大小端转换: LittleEndian:低位字节数据存放于低地址,高位字节数据存放于高地址. BigEn ...

最新文章

  1. 【算法+OpenCV】基于三次Bezier原理的曲线拟合算法C++与OpenCV实现
  2. pygame中使用事件扫描实现对按键的检测以及小游戏的编写
  3. Android Studio常用Plugin及 手动安装 Plugins
  4. KNN算法与Kd树(转载+代码详细解释)
  5. 遗传算法 差分进化算法 粒子群优化算法区别
  6. (干货分享)农商行中商业智能建设的整体思路与架构
  7. Oracle中的环境变量(ORACLE_HOME 和 ORACLE_SID)
  8. webgis之Openlayer加载wmts服务
  9. c语言编写成绩管理系统代码,C语言学生成绩管理系统源代码
  10. 平稳时间序列的相关概念
  11. c语言while的用法四种句型,有关while的几种用法
  12. php图片不显示怎么处理,如何解决php图片因存在错误而无法显示
  13. 计算9+99+999+……+999999999
  14. 递归求2+2+22+222+............
  15. 用ASP.NET建立一个在线RSS新闻聚合器
  16. Apache Kylin实践
  17. Matlab-RGB-颜色对照表(0-1之间取值)
  18. c++中“::”和“:” 冒号 意思
  19. VMware+Server2012+ASP.NET网站配置实验
  20. 阿里云【7天实践训练营】进阶路线——Day2:阿里云云计算助理工程师认证(ACA)课程1 ~ 2章

热门文章

  1. Android官方文档翻译-Broadcasts
  2. 日本“经营之神”稻盛和夫去世,终年90岁,人生信条:“每天都必须特别认真地生活。”...
  3. 测试开发该如何在团队中推广新工具、新技术(深度好文)
  4. docker manifest 使用实战
  5. [转]通过 BT 种子 Hash 值从 BitComet 服务器上下载种子文件
  6. 微信小程序-自定义导航栏及返回上一级页面的实现
  7. 小程序数据分析(有数)
  8. linux命令中:wq和:wq!区别
  9. Cookie、Session、本地存储
  10. 指针变量的类型及含义