Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

What is the method of redis to implement distributed reentrant lock

2025-01-15 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Database >

Share

Shulou(Shulou.com)05/31 Report--

This article mainly analyzes the relevant knowledge of what is the method of redis to achieve distributed reentry lock, the content is detailed and easy to understand, the operation details are reasonable, and has a certain reference value. If you are interested, you might as well follow the editor to take a look, and follow the editor to learn more about "what is the method of redis to achieve distributed reentry locks".

What is a non-reentrant lock?

That is, if the current thread executes a method that has acquired the lock, it will be blocked when it attempts to acquire the lock again in the method.

What is a reentrant lock?

A reentrant lock, also known as a recursive lock, means that the inner recursive function can still acquire the lock after the outer function acquires the lock in the same thread. That is, when the same thread enters the same code again, it can get the lock again.

The function of reentrant lock?

Prevents deadlocks from occurring by acquiring locks multiple times in the same thread.

Note: both synchronized and ReentrantLock are reentrant locks in java programming.

Reentrant lock based on synchronized

Step 1: double locking logic

Public class SynchronizedDemo {/ / simulated inventory 100 int count=100; public synchronized void operation () {log.info ("first Lock: inventory reduction"); / / simulated inventory reduction count--; add (); log.info ("order end inventory surplus: {}", count);} private synchronized void add () {log.info ("second Lock: insert order") Try {Thread.sleep (1000 to 10);} catch (InterruptedException e) {e.printStackTrace ();}

Step 2: add a test class

Public static void main (String [] args) {SynchronizedDemo synchronizedDemo=new SynchronizedDemo (); for (int I = 0; I

< 3; i++) { int finalI = i; new Thread(()->

{log.info ("- user {} starts placing an order -", finalI); synchronizedDemo.operation ();}) .start ();}}

Step 3: test

User 2 begins to place an order-20INFO com.agan.redis.controller.SynchronizedController 44 Thread-1 04.013 [Thread-1] INFO com.agan.redis.controller.SynchronizedController-- user 1 begins to place an order-20 INFO com.agan.redis.controller.SynchronizedController 44 Thread-1 04.013 [Thread-0] order -user 0 starts to place order-- 20 Thread-2 04.016 [Thread-2] INFO com.agan.redis.Reentrant.SynchronizedDemo-Tier 1 Lock: inventory reduction 20 INFO com.agan.redis.Reentrant.SynchronizedDemo 04.016 [Thread-2] Lock-Tier 2 Lock: insert order 20 INFO com.agan.redis.Reentrant.SynchronizedDemo 14.017 [Thread-2] Lock-end inventory remaining: 9920 INFO com.agan.redis.Reentrant.SynchronizedDemo 44 14.017 [Thread-0] INFO com.agan.redis.Reentrant.SynchronizedDemo-layer 1 lock: reduction of inventory 20 INFO com.agan.redis.Reentrant.SynchronizedDemo 44 INFO com.agan.redis.Reentrant.SynchronizedDemo [Thread-0] Lock-second lock: insert order 20 INFO com.agan.redis.Reentrant.SynchronizedDemo 44 Thread-0 24.017 [Thread-0] INFO com.agan.redis.Reentrant.SynchronizedDemo-end of order inventory remaining: 9820 INFO com.agan.redis.Reentrant.SynchronizedDemo 4415 [Thread-1] lock- Layer 1 lock: inventory reduction 20 Thread-1 44 Thread-1 24.017 [Thread-1] lock-second layer lock: insert order 20 Thread-1 44 Thread-1 34.017 [lock] lock-place order end inventory remaining: 97

Because the synchronized keyword modifies the method, all locks are instance objects: synchronizedDemo

As can be seen from the running results, both inventory reduction and order insertion are completed for each thread to complete the two methods before the lock can be released and other threads can hold the lock, that is, a thread can get the same lock multiple times and can be reentered. So synchronized is also a reentrant lock.

Reentrant lock based on ReentrantLock

ReentrantLock, which is a reentrant and exclusive lock, is a recursive non-blocking synchronous lock. Compared with the synchronized keyword, it is more flexible and powerful, and adds advanced functions such as polling, timeout, interrupt and so on.

Step 1: double locking logic

Public class ReentrantLockDemo {private Lock lock = new ReentrantLock (); public void doSomething (int n) {try {/ / enter the first thing recursive: lock lock.lock (); log.info ("- recursive {} times -", n) If (n {log.info ("- user {} start placing order -", finalI); reentrantLockDemo.doSomething (1);}) .start ();}}

Step 3: test

20 Thread-2 55 Thread-2 23.533 [Thread-1] Thread-0 -user 0 starts to place an order-- 20 Thread-1 55 Thread-1 23.536 [Thread-1] Thread-1-- Recursive 1 time-20 Thread-1 55 Thread-1 25.537 [Thread-1] INFO com-Recursive 2 times-20 Visu55 Thread-1 27.538 [Thread-1] INFO com .agan.redis.Reentrant.ReentrantLockDemo-Recursive 3 times-20 Thread-2 55virtual 27.538 [Thread-2] INFO com.agan.redis.Reentrant.ReentrantLockDemo-Recursive 1 time-20 Thread-2 55 Thread-2 29.538 [Reentrant] Demo-recursive 2 times: 55 Thread-2 31.539 [Thread-2] INFO com.agan.redis.Reentrant.ReentrantLockDemo-Recursive 3 times-20 Thread-0 55 Thread-2 31.539 [Thread-0] INFO com.agan.redis.Reentrant.ReentrantLockDemo-Recursive 1 time-20 Thread-0 55Rank 33.539 [Thread-0] INFO com.agan.redis.Reentrant.ReentrantLockDemo-Recursive 2-20 Thread-0 55-35. 540 [Thread-0] INFO com.agan.redis.Reentrant.ReentrantLockDemo-recursion 3 times-

As can be seen from the running results, each thread can be locked and unlocked multiple times, and the ReentrantLock is reentrant.

How does redis implement distributed reentrant locks?

Although setnx can implement distributed locks, it is not reentrant. In some complex business scenarios, when we need distributed reentrant locks, there are still many solutions for redis reentrant locks in the industry, and Redisson is the most popular one at present. [related recommendation: Redis video tutorial]

What is Redisson?

Redisson is the Java version of the Redis client officially recommended by Redis.

Based on the interfaces commonly used in the Java utility kit, a series of common tool classes with distributed characteristics are provided for users.

In the network communication, it is the Netty framework based on NIO, which ensures the high performance of the network communication.

In the function of distributed lock, it provides a series of distributed locks, such as:

Reentrant lock (Reentrant Lock)

Fair Lock (Fair Lock)

Unfair lock (unFair Lock)

Read-write lock (ReadWriteLock)

Interlocking (MultiLock)

Red lock (RedLock)

Case study: experience redis distributed reentrant lock

Step 1:Redisson configuration

Redisson configuration can be checked: redis distributed cache (34)-SpringBoot integrated Redission-Nuggets (juejin.cn)

Https://juejin.cn/post/7057132897819426824

Step 2:Redisson reentrant lock test class

Public class RedisController {@ Autowired RedissonClient redissonClient; @ GetMapping (value = "/ lock") public void get (String key) throws InterruptedException {this.getLock (key, 1);} private void getLock (String key, int n) throws InterruptedException {/ / simulated recursion, exit if (n > 3) {return after 3 recursions } / / step 1: acquire a distributed reentrant lock RLock / / distributed reentrant lock RLock: implements the java.util.concurrent.locks.Lock interface, and also supports automatic expiration and unlocking. RLock lock = redissonClient.getLock (key); / / step 2: try to get the lock / / 1. Default to take the lock / / lock.tryLock (); / / 2. Supports the function of unlocking after expiration, which is automatically unlocked after 10 seconds. There is no need to call the unlock method to manually unlock / / lock.tryLock (10, TimeUnit.SECONDS); / / 3. Try to lock, wait up to 3 seconds, and then automatically unlock / / lock.tryLock (3, 10, TimeUnit.SECONDS) after 10 seconds of expiration; boolean bs = lock.tryLock (3, 10, TimeUnit.SECONDS) If (bs) {try {/ / Business Code log.info ("Thread {} Business Logic processing: {}, Recursive {}", Thread.currentThread (). GetName (), key,n); / / Analog processing Business Thread.sleep (1000 * 5) / / simulate entering recursive this.getLock (key, + + n);} catch (Exception e) {log.error (e.getLocalizedMessage ());} finally {/ / step 3: unlock lock.unlock () Log.info ("thread {} unlock exit", Thread.currentThread (). GetName ());}} else {log.info ("thread {} did not acquire a lock", Thread.currentThread (). GetName ());}

Three locking actions for RLock:

Lock.tryLock ()

Hold the lock by default

Lock.tryLock (10, TimeUnit.SECONDS)

Support the function of unlocking after expiration, which can be unlocked automatically after 10 seconds

Lock.tryLock (3,10, TimeUnit.SECONDS)

Try to lock, wait up to 3 seconds, and unlock automatically after 10 seconds of expiration.

Difference:

Lock.lock (): blocking wait. All locks added by default are 30s.

Automatic renewal of the lock, if the business is too long, the new 30s will be locked automatically during operation. There is no need to worry about the automatic expiration of locks due to long business hours (default renewal)

As long as the locked business is completed, the current lock will not be renewed. Even if the lock is not unlocked manually, the default lock will automatically expire within 30 seconds, and there will be no deadlock problem.

Lock () if we do not specify a timeout for the lock, we use [watchdog default time]: lockWatchdogTimeout = 30 * 1000

Principle: as long as the lock is successfully occupied, a scheduled task [reset the expiration time of the lock, and the new expiration time is the default time for the watchdog] will be automatically renewed every 10 seconds, lasting for 30 seconds.

Lock.lock (10memeUnit.SECONDS): unlock automatically in 10 seconds. The automatic unlocking time must be longer than the business execution time.

Problem: after the lock time is up, it will not be renewed automatically

How it works: if we pass the timeout of the lock lock, we will send it to redis to execute the script to occupy the lock. The default timeout is the time we set.

Best actual combat:

Lock.lock (10memeUnit.SECONDS); save the watchdog renewal operation, the automatic unlocking time must be longer than the business execution time, and unlock manually.

Step 3: test

Visit 3 times: http://127.0.0.1:9090/lock?key=ljw

Thread http-nio-9090-exec-1 business logic processing: ljw, recursive 1 thread http-nio-9090-exec-2 does not acquire lock thread http-nio-9090-exec-1 business logic processing: ljw, recursive 2 thread http-nio-9090-exec-3 does not acquire lock thread http-nio-9090-exec-1 business logic processing: ljw Recursive 3-thread http-nio-9090-exec-1 unlock exit thread http-nio-9090-exec-1 unlock exit thread http-nio-9090-exec-1 unlock exit

Pass the test results:

The nio-9090-exec-1 thread recurses three times in the getLock method, which proves that lock.tryLock is a reentrant lock.

Only when the nio-9090-exec-1 thread finished executing, io-9090-exec-2 nio-9090-exec-3 did not acquire the lock because lock.tryLock (3, 10, TimeUnit.SECONDS) tried to lock it, waiting for up to 3 seconds, and automatically unlocked 10 seconds after it was locked, so it didn't wait 3 seconds, so it gave up.

This is the end of the introduction on "what is the method of redis to achieve distributed reentry locks". More related content can be searched for previous articles, hoping to help you answer questions and questions, please support the website!

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Database

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report