文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

Redisson可重入锁解锁逻辑是什么

2023-07-05 02:58

关注

这篇文章主要介绍“Redisson可重入锁解锁逻辑是什么”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“Redisson可重入锁解锁逻辑是什么”文章能帮助大家解决问题。

相比较Redisson可重入锁的加锁逻辑,释放锁的逻辑就相对简单一些。释放锁分为主动释放和自动释放两种方式。

主动释放

我们查看org.redisson.RedissonLock#unlock()方法:

public void unlock() {        try {            get(unlockAsync(Thread.currentThread().getId()));        } catch (RedisException e) {            if (e.getCause() instanceof IllegalMonitorStateException) {                throw (IllegalMonitorStateException) e.getCause();            } else {                throw e;            }        }//        Future<Void> future = unlockAsync();//        future.awaitUninterruptibly();//        if (future.isSuccess()) {//            return;//        }//        if (future.cause() instanceof IllegalMonitorStateException) {//            throw (IllegalMonitorStateException)future.cause();//        }//        throw commandExecutor.convertException(future);    }

同样采用异步的方式释放锁,unlockAsync():

public RFuture<Void> unlockAsync(long threadId) {    // 异步方式释放锁    RFuture<Boolean> future = unlockInnerAsync(threadId);    CompletionStage<Void> f = future.handle((opStatus, e) -> {        // 取消看门狗定时任务        cancelExpirationRenewal(threadId);        if (e != null) {            throw new CompletionException(e);        }        if (opStatus == null) {            IllegalMonitorStateException cause = new IllegalMonitorStateException("attempt to unlock lock, not locked by current thread by node id: "                    + id + " thread-id: " + threadId);            throw new CompletionException(cause);        }        return null;    });    return new CompletableFutureWrapper<>(f);}

可以看到,首先调用unlockInnerAsync()方法释放锁,在释放锁之后,执行cancelExpirationRenewal(threadId)取消看门狗自动续期的定时任务。

释放锁核心逻辑:

protected RFuture<Boolean> unlockInnerAsync(long threadId) {        return evalWriteAsync(getRawName(), LongCodec.INSTANCE, RedisCommands.EVAL_BOOLEAN,            "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.asList(getRawName(), getChannelName()), LockPubSub.UNLOCK_MESSAGE, internalLockLeaseTime, getLockName(threadId));}

Redisson可重入锁的释放还是通过LUA脚本实现,保证多个命令之间的原子性。

基本流程:

通过hexists指令判断锁是不是自己的,如果不是自己的锁,说明非法释放锁,返回nil,

如果是自己的锁,通过hincrby将锁的重入次数减1;

判断减1后的数是否大于0,如果减1后的数大于0,说明还没有完全释放锁,则重置锁的过期时间,并返回0;

如果减1后的数已经等于0,说明已经完全释放锁,则通过del指令释放锁,并通过publish发布一条消息,告诉其它订阅了这把锁的线程,我已经释放锁了,你们可以过来获取了;释放锁成功,返回1

其它情况,返回nil;

主动释放锁这块考虑的不仅仅是对 key 进行处理,因为可能存在重入锁,所以会先对 redis key 对应的 hash value 进行递减,相当于减去重入次数。

自动释放

当服务宕机时,看门狗不再看门,那么最多 30s 之后锁被自动释放;当设置锁的超时时间时,锁到了过期时间,自动释放。

关于“Redisson可重入锁解锁逻辑是什么”的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识,可以关注编程网行业资讯频道,小编每天都会为大家更新不同的知识点。

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯