redis面试(二十三)写锁释放

2024-08-27 10:20

本文主要是介绍redis面试(二十三)写锁释放,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

先加了写锁,后面再次加写锁或者读锁

anyLock: {
“mode”: “write”,
“UUID_01:threadId_01:write”: 2,
“UUID_01:threadId_01”: 1
}

写锁的释放lua脚本在这里
RedissonWriteLock.unlockInnerAsync()
在这里插入图片描述

比如说现在的参数是这
KEYS[1] = anyLock
KEYS[2] = redisson_rwlock:{anyLock}

ARGV[1] = 0
ARGV[2] = 30000
ARGV[3] = UUID_01:threadId_01:write

下面来分析一下lua脚本

local mode = redis.call(‘hget’, KEYS[1], ‘mode’);
if (mode == false) then
redis.call(‘publish’, KEYS[2], ARGV[1]);

这几行不用多说,先获取anyLock这个hash表中key为mode对应的值,如果不存在的话,锁肯定是已经释放或者过期了

if (mode == ‘write’) then
如果是写锁的话才会继续执行,不是的话直接返回1

local lockExists = redis.call(‘hexists’, KEYS[1], ARGV[3]);
if (lockExists == 0) then

判断anyLock这个hash表中key=UUID_01:threadId_01:write 是否存在,存在的话证明这个线程对应的写锁是存在的,不存在的话直接返回null

local counter = redis.call(‘hincrby’, KEYS[1], ARGV[3], -1);
if (counter > 0) then
redis.call(‘pexpire’, KEYS[1], ARGV[2]);

现在已经确定写锁是存在的,并且需要释放,那这个参数hincrby之前见过好多次了,就是增量更新命令,这里给的是-1,所以是将anyLock这个hash表中key=UUID_01:threadId_01:write,对应的value值-1,并且返回更新后的值。这里就是处理可重入锁的逻辑

如果这个更新后的值大于0的话,证明还有读锁需要释放,这个锁不能过期,那就更新一下过期时间。

redis.call(‘hdel’, KEYS[1], ARGV[3]);
走到这里的话,证明这个写锁没有重入,那就删除anyLock这个hash表中key=UUID_01:threadId_01:write的键值对。

if (redis.call(‘hlen’, KEYS[1]) == 1) then
redis.call(‘del’, KEYS[1]);
redis.call(‘publish’, KEYS[2], ARGV[1]);

这个命令就很有意思了,hlen命令是获取anyLock这个hash表中还有多少键值对,如果是1个的话,那肯定是只剩下mode这个key了,删除这个anyLock,广播一下就结束了

但是如果大于1个的话,就说明还有其他的key
那什么情况下还会有多余的key呢,写锁是互斥的,只能重入,但是可重入的逻辑在上面已经处理过了。那这里的其他key就只能是这个线程后来加的读锁了。
所以这里就是为了处理写锁+读锁的情况

redis.call(‘hset’, KEYS[1], ‘mode’, ‘read’);
如果释放完写锁,还存在其他锁,那这个锁一定是读锁,所以就将mode变成read,此时这个写锁就完全变成读锁了,等待读锁逻辑的处理。

这篇关于redis面试(二十三)写锁释放的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1111391

相关文章

字节面试 | 如何测试RocketMQ、RocketMQ?

字节面试:RocketMQ是怎么测试的呢? 答: 首先保证消息的消费正确、设计逆向用例,在验证消息内容为空等情况时的消费正确性; 推送大批量MQ,通过Admin控制台查看MQ消费的情况,是否出现消费假死、TPS是否正常等等问题。(上述都是临场发挥,但是RocketMQ真正的测试点,还真的需要探讨) 01 先了解RocketMQ 作为测试也是要简单了解RocketMQ。简单来说,就是一个分

零基础学习Redis(10) -- zset类型命令使用

zset是有序集合,内部除了存储元素外,还会存储一个score,存储在zset中的元素会按照score的大小升序排列,不同元素的score可以重复,score相同的元素会按照元素的字典序排列。 1. zset常用命令 1.1 zadd  zadd key [NX | XX] [GT | LT]   [CH] [INCR] score member [score member ...]

秋招最新大模型算法面试,熬夜都要肝完它

💥大家在面试大模型LLM这个板块的时候,不知道面试完会不会复盘、总结,做笔记的习惯,这份大模型算法岗面试八股笔记也帮助不少人拿到过offer ✨对于面试大模型算法工程师会有一定的帮助,都附有完整答案,熬夜也要看完,祝大家一臂之力 这份《大模型算法工程师面试题》已经上传CSDN,还有完整版的大模型 AI 学习资料,朋友们如果需要可以微信扫描下方CSDN官方认证二维码免费领取【保证100%免费

java面试常见问题之Hibernate总结

1  Hibernate的检索方式 Ø  导航对象图检索(根据已经加载的对象,导航到其他对象。) Ø  OID检索(按照对象的OID来检索对象。) Ø  HQL检索(使用面向对象的HQL查询语言。) Ø  QBC检索(使用QBC(Qurey By Criteria)API来检索对象。 QBC/QBE离线/在线) Ø  本地SQL检索(使用本地数据库的SQL查询语句。) 包括Hibern

Redis中使用布隆过滤器解决缓存穿透问题

一、缓存穿透(失效)问题 缓存穿透是指查询一个一定不存在的数据,由于缓存中没有命中,会去数据库中查询,而数据库中也没有该数据,并且每次查询都不会命中缓存,从而每次请求都直接打到了数据库上,这会给数据库带来巨大压力。 二、布隆过滤器原理 布隆过滤器(Bloom Filter)是一种空间效率很高的随机数据结构,它利用多个不同的哈希函数将一个元素映射到一个位数组中的多个位置,并将这些位置的值置

Lua 脚本在 Redis 中执行时的原子性以及与redis的事务的区别

在 Redis 中,Lua 脚本具有原子性是因为 Redis 保证在执行脚本时,脚本中的所有操作都会被当作一个不可分割的整体。具体来说,Redis 使用单线程的执行模型来处理命令,因此当 Lua 脚本在 Redis 中执行时,不会有其他命令打断脚本的执行过程。脚本中的所有操作都将连续执行,直到脚本执行完成后,Redis 才会继续处理其他客户端的请求。 Lua 脚本在 Redis 中原子性的原因

贝壳面试:什么是回表?什么是索引下推?

尼恩说在前面 在40岁老架构师 尼恩的读者交流群(50+)中,最近有小伙伴拿到了一线互联网企业如得物、阿里、滴滴、极兔、有赞、希音、百度、网易、美团的面试资格,遇到很多很重要的面试题: 1.谈谈你对MySQL 索引下推 的认识? 2.在MySQL中,索引下推 是如何实现的?请简述其工作原理。 3、说说什么是 回表,什么是 索引下推 ? 最近有小伙伴在面试 贝壳、soul,又遇到了相关的

laravel框架实现redis分布式集群原理

在app/config/database.php中配置如下: 'redis' => array('cluster' => true,'default' => array('host' => '172.21.107.247','port' => 6379,),'redis1' => array('host' => '172.21.107.248','port' => 6379,),) 其中cl

Redis的rehash机制

在Redis中,键值对(Key-Value Pair)存储方式是由字典(Dict)保存的,而字典底层是通过哈希表来实现的。通过哈希表中的节点保存字典中的键值对。我们知道当HashMap中由于Hash冲突(负载因子)超过某个阈值时,出于链表性能的考虑,会进行Resize的操作。Redis也一样。 在redis的具体实现中,使用了一种叫做渐进式哈希(rehashing)的机制来提高字典的缩放效率,避

毕业前第二次面试的感慨

距面试已经过去了有几天了,我现在想起来都有说多的恨感慨。 我一直都是想找刚刚起步的企业,因为这能让我学到更多的东西,然而正好有一家企业是刚起步的,而且他还有自己的产品专利,可以说这是一家,即是创业又是刚起步的公司,这家公司回复了我投给他的简历,这家企业想进一步了解我的情况,因为简历上我符合这家企业的基本要求,所以要进一步了解。 虽然面试的过程中,他给我的面试题,我做得并不是很理想,