In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-03-30 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >
Share
Shulou(Shulou.com)06/03 Report--
This article will explain in detail the example analysis of ReentrantLock reentry lock for you. The editor thinks it is very practical, so I share it for you as a reference. I hope you can get something after reading this article.
1. Introduction of ReentrantLock
ReentrantLock reentry lock is a class that implements the Lock interface, and it is also a lock that is frequently used in practical programming. It supports reentry, which means that the shared resource can be locked repeatedly, that is, the current thread acquires the lock again will not be blocked. In the java keyword synchronized implicitly supports reentrancy (see this article on synchronized), synchronized achieves reentry by getting self-increment and releasing self-subtraction. At the same time, ReentrantLock also supports fair locking and unfair locking.
So, if you want to understand ReentrantLock completely, it is mainly the learning of ReentrantLock synchronization semantics: 1. The realization principle of reentrancy; 2. Fair lock and unfair lock.
two。 The implementation principle of reentrancy
To support reentrancy, two issues need to be solved:
1. When a thread acquires a lock, it directly succeeds again if the thread that has acquired the lock is the current thread.
two。 Since the lock will be acquired n times, the lock will be fully released only after the lock has been released the same n times.
Through this article, we know that synchronization components mainly express their synchronization semantics by rewriting several protected methods of AQS.
For the first question, let's take a look at how ReentrantLock is implemented. Take unfair lock as an example to determine whether the current thread can acquire a lock. The core method is nonfairTryAcquire:
Final boolean nonfairTryAcquire (int acquires) {final Thread current = Thread.currentThread (); int c = getState (); / / 1 If the lock is not occupied by any thread, the lock can be acquired by the current thread if (c = = 0) {if (compareAndSetState (0, acquires)) {setExclusiveOwnerThread (current); return true;}} / / 2. If occupied, check whether the occupying thread is the current thread else if (current = = getExclusiveOwnerThread ()) {/ / 3. Get again, count plus an int nextc = c + acquires;if (nextc < 0) / / overflowthrow new Error ("Maximum lock count exceeded"); setState (nextc); return true;} return false;}
The logic of this code is also very simple, please see the comments for details.
In order to support reentrancy, the processing logic is added in the second step. If the lock is already occupied by the thread, it will continue to check whether the occupying thread is the current thread. If so, the synchronization status plus 1 returns true, indicating that success can be obtained again.
Each re-acquisition will add one to the synchronization state, so what is the idea of processing when it is released? (still take unfair lock as an example) the core method is tryRelease:
Protected final boolean tryRelease (int releases) {/ 1. Synchronization status minus 1int c = getState ()-releases;if (Thread.currentThread ()! = getExclusiveOwnerThread ()) throw new IllegalMonitorStateException (); boolean free = false;if (c = 0) {/ / 2. Only when the synchronization status is 0, the lock is released successfully and returns truefree = true;setExclusiveOwnerThread (null);} / / 3. Lock is not fully released, return falsesetState (c); return free;}
For the logic of the code, see the comments. It should be noted that the release of the reentrant lock will not be considered successful until the synchronization state is 0, otherwise the lock has not been released. If the lock is acquired n times, it is released once. The lock is not fully released and returns false. Only when it is released n times can it be considered to be successfully released, and true is returned.
By now we can sort out the reentrant implementation of ReentrantLock, that is, the first piece of synchronization semantics.
3. Fair Lock and Fair Lock
ReentrantLock supports two types of locks: fair locks and unfair locks.
What is fairness is for acquiring locks. If a lock is fair, then the lock acquisition order should be in accordance with the absolute chronological order on the request, satisfying the FIFO. When there is no parameter, the construction method of ReentrantLock is to construct an unfair lock. The source code is:
Public ReentrantLock () {sync = new NonfairSync ();}
In addition, another way is provided. You can pass in a Boolean value, which is a fair lock in true and an unfair lock in false. The source code is:
Public ReentrantLock (boolean fair) {sync = fair? New FairSync (): new NonfairSync ();}
In the above unfair lock acquisition (nonfairTryAcquire method), it simply acquires the current state and does some logical processing, without taking into account the situation of threads waiting in the current synchronization queue.
Let's take a look at the handling logic of fair locks. The core approach is:
Protected final boolean tryAcquire (int acquires) {final Thread current = Thread.currentThread (); int c = getState (); if (c = = 0) {if (! hasQueuedPredecessors () & & compareAndSetState (0, acquires)) {setExclusiveOwnerThread (current); return true;} else if (current = = getExclusiveOwnerThread ()) {int nextc = c + acquires;if (nextc < 0) throw new Error ("Maximum lock count exceeded"); setState (nextc); return true;} return false;}}
The logic of this code is basically the same as that of nonfairTryAcquire, the only difference is that the logic judgment of hasQueuedPredecessors is added. The method name can be used to judge whether the current node has a precursor node in the synchronization queue. If there is a precursor node indicating that a thread requests resources earlier than the current thread, according to fairness, the current thread fails to request resources. If the current node does not have a precursor node, it is necessary to make a later logical judgment.
The fair lock acquires the lock from the first node in the synchronization queue every time, while the unfair lock is not necessarily, and it is possible that the thread that has just released the lock can acquire the lock again.
Fair lock VS unfair lock
Each time the fair lock acquires the lock as the first node in the synchronization queue, it ensures the absolute order of the time of requesting resources, while the unfair lock may continue to acquire the lock the next time the thread just released the lock. It is possible that other threads will never be able to acquire the lock, resulting in "hunger".
In order to ensure the absolute order of time, fair lock needs frequent context switching, while unfair lock will reduce the context switching and performance overhead. Therefore, ReentrantLock chooses unfair locks by default to reduce some context switching and ensure greater throughput of the system.
This is the end of this article on "sample analysis of ReentrantLock reentry locks". I hope the above content can be of some help to you, so that you can learn more knowledge. if you think the article is good, please share it for more people to see.
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: 219
*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.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.