java lock (VI): non-reentrant lock reentrant lock VS

Reentrant lock known recursive lock means when the same thread acquires the lock of the outer layer method, and then into the inner thread of the method of automatically acquire the lock (provided that have the same lock object or object class), not because before has not been released and get blocked. ReentrantLock in Java and are synchronized reentrant lock, a lock reentrant advantage is to some extent to avoid deadlock. The following example code used for analysis:


15069189-8c738b8149d20e9c.png
image.png

In the above code, the two methods in a class are built is locked synchronized modified, doSomething () method call doOthers () method. Because the built-in locks are reentrant, so the same thread can obtain the current lock object when calling doOthers () directly into doOthers () operation.

If you get the current object is a non-reentrant lock, then the current thread before calling doOthers () needs to be performed doSomething () locks freed, in fact, the object lock has been held by the current thread, and can not be released. So this time there will be a deadlock.

And why reentrant lock can be automatically locked when the nested call it? We are by way of illustration and source code to resolve it.

Or example to draw water, a number of people in the queue to fetch water, this time allows multiple administrators to lock the bucket and the same person bindings. After this man with multiple buckets to fetch water when the first lock and a bucket of water binding and so after the second bucket can also bind directly and locks and began to draw water, all the water buckets are finished people will the lock returned to the administrator. All the people are able to successfully execute the process to draw water, waiting for the follow-up of people who can hit the water. This is reentrant lock.


15069189-be89ed6c58c6dfb3.png
image.png

However, if a non-reentrant lock, then the administrator at this time only to allow the lock and the same person in a bucket binding. After playing the first bucket of water and lock binding and does not release the lock, leads to the second bucket is not binding and can not draw water lock. The current thread deadlock, all threads throughout the waiting queue could not be awakened.


15069189-57301da2da49f56d.png
image.png

Before we said ReentrantLock are synchronized and re-entry lock, so let's compare by reentrant lock ReentrantLock source and non-reentrant lock NonReentrantLock analysis of why non-reentrant lock deadlock occurs when repeated calls to synchronize resources.

First ReentrantLock and AQS NonReentrantLock inherit parent class, a parent class AQS maintained in a synchronization state status to count the number of re-entry, status initial value is 0.

When a thread attempts to acquire a lock, the lock reentrant first attempt to obtain and update the status value, if the status == 0 indicates that no other thread synchronization code execution, put the status is set to 1, the current thread begins execution. If the status! = 0, it is determined whether the current thread is the thread acquired the lock, and if so execution status + 1, and the current thread can acquire the lock again. And not reentrant lock is a direct attempt to obtain and update the status of the value, if status! = 0, then it will lead to failure to acquire the lock, the current thread blocked.

When the lock is released, the same reentrant lock to get the current value of the status of the current thread is held under the premise of the lock. If status - 1 == 0, then the current thread acquires the lock repeat all operations have been executed, then the thread will lock being released. And not reentrant lock is in determining the current thread after thread holding the lock is directly status is set to 0, the lock is released.


15069189-9c70c5c3a2204b91.png
image.png

Reproduced in: https: //www.jianshu.com/p/a3056648dad5

Guess you like

Origin blog.csdn.net/weixin_34289454/article/details/91272392