preface

Redisson also supports reentrant read-write locks, allowing multiple read locks and one write lock to be locked simultaneously in a distributed scenario.

Use read/write locks

The Redisson read-write lock implements ReadWriteLock under JUC and is used in much the same way.

The source code

The lock source is basically the same as the previous reentrant lock, the only difference is in the Lua script.

So let’s focus on the Lua script.

Read lock source

Source address: org. Redisson. RedissonReadLock# tryLockInnerAsync

Parameter list:

  1. Keys [1] : Name of lock anyRWLock
  2. Keys [2] : lock timeout key{lock name}:UUID:ThreadId:rwlock_timeoutString, {anyRWLock}:e70b1307-9ddd-43de-ac9d-9c42b5c99a0d:1:rwlock_timeout
  3. ARGV[1] : lock time, default 30s
  4. ARGV[2] : current thread,UUID:ThreadIdThe string composed of e70b1307-9ddd-43de-ac9d-9c42b5c99a0d:1
  5. ARGV[3] : Write the lock name,getWriteLockName(threadId)Write the lock name,UUID:ThreadId:writeThe string consists of e70b1307-9ddd-43de-ac9d-9c42b5c99a0d:1:write

Read the lock for the first time

  1. Lock does not exist, go straight to the first part
  2. The mode of anyRWLock is read, indicating that it is a read lock
  3. Set the value e70b1307-9ddd-43de-ac9d-9c42b5c99a0d:1 (current thread) for lock anyRWLock to 1
  4. Set the lock {anyRWLock}:e70b1307-9ddd-43de-ac9d-9c42b5c99a0d:1:rwlock_timeout:1, which represents the timeout for the current thread and the current reentrant
  5. Sets the expiration time of two rediskeys
Read the reentrant lock

In the case of reentrant:

  1. The lock exists, is a read lock, and goes straight to Part 2
  2. For anyRWLock e70b1307-9ddd-43de-ac9d-9c42b5c99a0d:1 (current thread) value increment table is reentrant
  3. {anyRWLock}:e70b1307-9ddd-43de-ac9d-9c42b5c99a0d:1:rwlock_timeout:2 = timeout for the second lock
Read support

  1. Lock exists, enter the second part
  2. Increments the value of the current thread, which is already the second thread
  3. Sets the timeout time of the second thread {anyRWLock}:7c390320-78e3-497f-a3d8-ac34a44d0464:48:rwlock_timeout:1
Write read mutually exclusive

The read lock has been added, and the write lock is entered, which does not satisfy the first part or the second part, so it simply returns the remaining time of the current lock.

Then do a while (true) spin wait in your Java code.

As can be seen from the above, when reading a lock:

  1. The lock anyRWLock is hash-table structured
  2. When locking the hash table, the mode field is set to indicate whether the lock is a read or write lock.mode = readSaid read lock
  3. When locking, the hash table is set to anyRWLock for the current threadUUID:ThreadIdField with a value representing the number of reentrants
  4. Each time a lock is added, an additional key is maintained representing the timeout of the lock. The structure of this key is{lock name}:UUID: threaId :rwlock_timeout: number of reentrances

Write locks source

Source address: org. Redisson. RedissonWriteLock# tryLockInnerAsync

Parameter list:

  1. Keys [1] : Current lock anyRWLock
  2. ARGV[1] : lock time, default 30s
  3. ARGV[2] : Write the lock name,UUID:ThreadId:writeConstruct the string c69a9ed4-5c30-4952-814e-c0b94ad03a7f:1:write

Writing the lock source code is relatively easy to understand:

  1. To determine the mode of the lock, write the lock
  2. The lock is not created directly
  3. Lock exists, and then judge whether it is their own, is their reentry

So if you look at this, you can see that it’s directly satisfied, write and write mutex, read and write mutex, and the current thread can reenter.

conclusion

This is basically the end of read and write lock, read lock implementation is a little more complicated, write lock simple and clear.

When reading locks:

  1. The lock anyRWLock is a hash table structure
  2. When locking the hash table, the mode field is set to indicate whether the lock is a read or write lock.mode = readSaid read lock
  3. When locking, the hash table is set to anyRWLock for the current threadUUID:ThreadIdField with a value representing the number of reentrants
  4. Each time a lock is added, an additional key is maintained representing the timeout of the lock. The structure of this key is{lock name}:UUID: threaId :rwlock_timeout: number of reentrances

When writing locks:

  1. The lock anyRWLock is a hash table structure
  2. When locking the hash table, the mode field is set to indicate whether the lock is a read or write lock.mode = writeSaid write lock
  3. An additional field is maintained in anyRWLockUUID:ThreadId:writeIs the number of reentrants

As for guard dogs, these are the same as before, so I won’t introduce them.

Related to recommend

  • Redisson distributed lock source 09: Redlock RedLock story
  • Redisson distributed lock source 08: Multilock lock and lock release
  • Redisson distributed lock source 07: fair lock release