This article is from: Le Byte
The main explanation of the article is: Redisson
For more information related to JAVA can pay attention to the public number “Le Byte” send: 999
Let’s take a look at what Redis has to say about distributed locks:
The framework for the Java version of distributed locking is Redisson.
What is a Redisson?
If you’re already using Redis, you’ll get a lot more done using Redson, which provides the easiest and most convenient way to use Redis.
The goal of Redisson is to facilitate the Separation of Concern for Redisso that users can focus more on dealing with the business logic.
Redisson is a Java in-memory Data Grid implemented on the basis of Redis.
Second, integrate Redisson
There are two ways for Spring Boot to integrate Redisson:
This article describes how to programmatically integrate Redisson.
2.1 Introduction of Maven dependencies
Introducing the Maven dependency of Redisson in the pom.xml of the passjava-question microservice.
2.2 Custom configuration classes
The following code is a single node Redis configuration.
2.3 Test configuration classes
Create a new unit test method.
So we run this test method, and we print out the RedissonClient
Distributed reentrant locking
3.1 Reentrant lock test
Based on Redis Redisson distributed reentrant Lock RLockJava object implements the Java. Util. Concurrent. The locks. Lock interface. It also provides asynchronous (Async), Reactive (Reactive) and RXJava2 interfaces.
We used the open source PassJava project to test two points for reentrant locks:
3.1.1 Verification 1: Is the reentrant lock blocked?
To verify the above two points, I wrote a demo program: the flow of the code is to set the wukong-lock, add the lock, print the thread ID, wait for 10 seconds to release the lock, and finally return the response: “test lock OK”.
Verify the first point and test the preemptive lock with two HTTP requests.
The requested URL:
The first thread has a thread ID of 86. After 10 seconds, the lock is released. In the meantime, the second thread waits for the lock to be released.
After the first thread releases the lock, the second thread acquires the lock and, 10 seconds later, releases the lock.
I drew a flowchart to help you understand. As shown in the figure below:
It follows from this that Redisson’s reentrant lock blocks other threads and needs to wait for them to release it.
3.1.2 Verification 2: When the service stops, will the lock be released?
If thread A is waiting and the service suddenly stops, will the lock be released? If it is not released, it becomes a deadlock, blocking other threads from acquiring the lock.
Let’s first look at the result of Redis client query after thread A acquires the lock, as shown in the figure below:
Wukong-lock has a value, and you can see that the TTL is getting smaller, which means that Wukong-lock has an expiration time.
By observation, after 30 seconds, Wukong-lock expired and disappeared. After the shutdown of Redisson, the occupied lock will be released automatically.
So how does that work? There’s a concept here, watchdog.
3.2 Watchdog principle
If the Redisson node responsible for storing the distributed lock is down and the lock happens to be in a locked state, the lock will be locked. To prevent this from happening, Redisson provides an internal lock watchdog that continuously extends the lock’s validity before the Redisson instance is closed.
By default, the watchdog check lock timeout time is 30 seconds, but can be by modified Config. LockWatchdogTimeout to specify separately.
If we do not specify a timeout for Lock, we use 30 seconds as the watchdog’s default time. Once the lock is successfully held, a timer task is launched that resets the lock every 10 seconds to an expiration time of 30 seconds.
As shown in the figure below:
3.3 Set the lock expiration time
Lock can also be unlocked automatically by setting an expiration date.
As shown below, the lock automatically expires after 8 seconds.
If the execution time exceeds 8 seconds, manually releasing the lock will report an error, as shown in the figure below:
Therefore, if we set the automatic expiration time of the lock, the execution time must be less than the automatic expiration time of the lock, otherwise it will report an error.
Four, the king of the scheme
Because Redisson isso powerful and the solution for implementing distributed locking isso simple, it is called the king solution.
The schematic diagram is as follows:
The code is as follows:
Compared to the previous Redis scheme, it is much simpler.
Here’s a look at some of the other distributed locks in Redisson that you’ll need in future projects.
5. Distributed read-write locks
Based on Redis Redisson distributed re-entrant read-write lock RReadWriteLock Java object implements the Java. Util. Concurrent. The locks. ReadWriteLock interface. Both the read lock and the write lock inherit the RLock interface.
A write lock is an exclusive lock (mutex) and a read lock is a shared lock.
The sample code is as follows:
In addition, Redisson also provides a LeaseTime parameter to specify the lock time through the lock method. After this time, the lock is released automatically.
6. Distributed semaphore
Based on Redis Redisson distributed signal (Semaphore) Java objects RSemaphore adopted with Java. Util. Concurrent. The Semaphore similar interface and usage. It also provides asynchronous (Async), Reactive (Reactive) and RXJava2 interfaces.
Now, if you think about the use of semaphore, you have three parking Spaces, and when the three Spaces are full, the other cars stop. A parking space can be compared to a signal. Now there are three signals, stop once, use up one signal, and release one signal when the car leaves.
Let’s use Redisson to demonstrate the parking space above.
First define a way to occupy a parking space:
Define another way to get out of a parking space:
For simplicity, I used the Redis client to add a key: “park”. The value is equal to 3, which means the semaphore is park. There are three values in total.
Then use PostMan to send a Park request to occupy a parking space.
Then check the value of park in the Redis client and find that it has been changed to 2. Continue to call twice and find that park is equal to 0. When calling the fourth time, it will find that the request has been waiting, indicating that there is not enough parking space. If you want to avoid blocking, you can use tryAcquire or tryAcquireAsync.
Then we call the method to leave the parking space, and the value of park is changed to 1, which means there is 1 parking space left.
Note: When you release the semaphore multiple times, the remaining semaphore will continue to grow, instead of being capped after 3.
Other distributed locks:
Thank you for your recognition and support, Xiaobian will continue to forward “Le Byte” quality articles