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

How to realize Java reentrant distributed lock

2025-02-24 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >

Share

Shulou(Shulou.com)06/02 Report--

This article focuses on "how to achieve Java reentrant distributed locks", interested friends may wish to take a look. The method introduced in this paper is simple, fast and practical. Now let the editor take you to learn "how to achieve Java reentrant distributed locks"!

Reentrant

Speaking of reentrant locks, let's first take a look at a reentrant explanation from wiki:

If a program or subroutine can be "interrupted at any time and then scheduled by the operating system to execute another piece of code, which calls the subroutine without error", it is called reentrant (reentrant or re-entrant). That is, when the subroutine is running, the execution thread can enter and execute it again, and still get the results expected at the time of the design. Unlike thread safety in multithreaded concurrent execution, reentrant emphasizes that it is still safe to re-enter the same subroutine when executing on a single thread.

When a thread executes a piece of code to acquire the lock successfully, when it continues to execute, it encounters the locked code, reentrability ensures that the thread can continue to execute, and non-reentrant means that it needs to wait for the lock to release and acquire the lock successfully again before it can continue to execute.

Explain the reentrant with a piece of Java code:

Public synchronized void a () {b ();} public synchronized void b () {/ / pass}

Suppose the X thread continues to execute the b method after the a method acquires the lock, and if it cannot be reentered at this time, the thread must wait for the lock to be released and scramble for the lock again.

The lock is obviously owned by the X thread, but you still need to wait for the lock to be released by yourself, and then grab the lock, which seems strange. I release myself.

Reentrancy can solve this awkward problem. When a thread has a lock, it encounters a locking method later, directly increasing the number of locks by 1, and then executing the method logic. After exiting the locking method, the number of locks is reduced by 1, and when the number of locks is 0, the lock is really released.

You can see that the biggest feature of the reentrant lock is counting and calculating the number of times the lock is added. So when reentrant locks need to be implemented in a distributed environment, we also need to count the number of locks added.

There are two ways to implement distributed reentrant locks:

Implementation scheme based on ThreadLocal

Implementation scheme based on Redis Hash

First, let's take a look at the implementation based on ThreadLocal.

Implementation scheme based on ThreadLocal

Mode of realization

ThreadLocal in Java allows each thread to have its own instance copy, and we can use this feature to count the number of thread reentrants.

Let's define a global variable LOCKS for ThreadLocal, which stores the Map instance variable in memory.

Private static ThreadLocal LOCKS = ThreadLocal.withInitial (HashMap::new)

Each thread can get its own instance of Map through ThreadLocal, where key stores the name of the lock in Map, and value stores the number of times the lock is reentered.

The code for locking is as follows:

/ * * reentrant lock * * @ param lockName lock name means you need to compete for critical resources * @ param request unique identification. You can use uuid to determine whether you can re-enter * @ param leaseTime lock release time * @ param unit lock release time unit * @ return * / public Boolean tryLock (String lockName, String request, long leaseTime, TimeUnit unit) {Map counts = LOCKS.get () If (counts.containsKey (lockName)) {counts.put (lockName, counts.get (lockName) + 1); return true;} else {if (redisLock.tryLock (lockName, request, leaseTime, unit)) {counts.put (lockName, 1); return true;}} return false;}

"ps: redisLock#tryLock is the distributed lock implemented in the previous article. As the chain outside the public name can not jump directly, pay attention to" program information "and reply to the distributed lock to get the source code.

The locking method first determines whether the current thread already owns the lock, and if so, directly adds 1 to the number of reentrants of the lock.

If you do not already have the lock, try to add the lock to Redis. After the lock is successful, add 1 to the number of reentrants.

The code to release the lock is as follows:

/ * unlocking requires judging different thread pools * * @ param lockName * @ param request * / public void unlock (String lockName, String request) {Map counts = LOCKS.get (); if (counts.getOrDefault (lockName, 0))

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

Development

Wechat

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

12
Report