当前位置: 首页 > 科技观察

Redisson分布式锁源码10:读写锁

时间:2023-03-13 19:46:14 科技观察

前言Redisson也支持可重入的读写锁,在分布式场景下可以同时锁定多个读锁和一个写锁。1、使用读写锁Redisson读写锁在JUC下实现ReadWriteLock,使用方法基本相同。2.源码加锁源码和前面的可重入锁基本一样。唯一的区别在于Lua脚本。所以下面着重分析Lua脚本。读取锁源码源码地址:org.redisson.RedissonReadLock#tryLockInnerAsync参数列表:KEYS[1]:锁名anyRWLockKEYS[2]:锁超时key{锁名}:UUID:ThreadId:rwlock_timeoutstring,{anyRWLock}:e70b1307-9ddd-43de-ac9d-9c42b5c99a0d:1:rwlock_timeoutARGV[1]:锁定时间,默认30sARGV[2]:当前线程,UUID:ThreadId组成的字符串,e70b1307-9ddd-43de-ac9d-9c42b5c99a0d:1ARGV[3]:写锁名,getWriteLockName(threadId)写锁名,UUID:ThreadId:write组成的字符串,e70b1307-9ddd-43de-ac9d-9c42b5c99a0d:1:write第一个读锁不存在,直接转到第一个parttosetlockanyRWLockmodeisread,表示这是读锁setlockanyRWLocke70b1307-9ddd-43de-ac9d-9c42b5c99a0d:1(currentthread)valueis1setthelock{anyRWLock}:e70b1307-9ddd-43de-ac9d-9c42b5c99a0d:1:rwlock_timeout:1的值为1,表示当前线程,当前重入超时时间设置了两个RedisKey的过期时间秒。读锁重入如果是可重入:锁存在并且是读锁,直接进入锁的第二部分anyRWLocke70b1307-9ddd-43de-ac9d-9c42b5c99a0d:1(currentthread)valueauto-increment1tableisre-entryre-create{anyRWLock}:e70b1307-9ddd-43de-ac9d-9c42b5c99a0d:1:rwlock_timeout:2表示读读支持锁存在第二个锁的超时时间,进入第二部分,增加值当前线程减1,这里已经是第二个线程了设置第二个线程{anyRWLock}:7c390320-78e3-497f-a3d8-ac34a44d0464:48:rwlock_timeout:1rwlock_timeout的超时时间:1写读互斥锁加了读锁。这时候写锁进来了,不满足第一部分或者第二部分,所以直接返回当前锁,剩下的时间再在Java代码中执行while(true)自旋等待。从上面可以看出,在读锁的时候:当锁anyRWLock是哈希表结构的锁时,会在哈希表中设置mode字段来表示这个锁是读锁还是写锁,而mode=read表示读锁加锁,此时会将当前线程anyRWLock的UUID:ThreadId字段设置到哈希表中,该值表示重入次数。每加一把锁,都会维护一个额外的key来表示这次加锁的超时时间。这个key的结构是{lockname}:UUID:ThreadId:rwlock_timeout:Reentrytimes写锁源码源地址:org.redisson.RedissonWriteLock#tryLockInnerAsync参数列表:KEYS[1]:当前锁anyRWLockARGV[1]:lock时间,默认30sARGV[2]:写锁名称,由UUID:ThreadId:write,c69a9ed4-5c30-4952-814e-c0b94ad03a7f:1:write组成的字符串写锁源码比较容易理解:判断锁是写锁不存在,直接创建锁,然后判断是否是自己,如果是自己,则重新进入,可见直接满足,写写互排斥,读写互斥,当前线程可以再次重入。3.综上所述,到这里读写锁基本上就读完了。读锁的实现稍微复杂一点,写锁简单明了。读锁时:当锁anyRWLock为哈希表结构锁时,mode字段会被设置为哈希表,表示该锁是读锁还是写锁,mode=read表示当读锁被锁定,哈希表将被锁定设置当前线程的UUID:ThreadId字段anyRWLock。该值表示重新进入的次数。每加一把锁,都会维护一个额外的key来表示这个锁的超时时间。这个key的结构是{lockname}:UUID:ThreadId:rwlock_timeout:repeat写锁时的条目数:当锁anyRWLock是哈希表结构锁时,会在哈希表中设置mode字段为表示该锁是读锁还是写锁,mode=write表示写锁在任意RWLock中额外维护一个字段UUID:ThreadId:write表示重入次数。至于watchdog,这些和之前的一样,就不多做介绍了。本文转载自微信公众号“程序员小航”,可通过以下二维码关注。转载本文请联系程序员小航公众号。