The Java reentrant and non-reentrant lock latch

Simple application locks


With the lock to ensure atomicity (this.count ++ code called critical region)

What is atomic, that is inseparable from the beginning to the end of execution, other threads can not be executed simultaneously.

Atomic operations may be achieved by CAS

CAS(Compare and Swap):

CAS operation requires two input values, an old value (a desired value before the operation) and a new value, during operation of the old first comparison values ​​are not changed, if the change does not occur, before switching to a new value, changes no exchange.

CAS is achieved primarily through compareAndSwapXXX () method, and the implementation of this method is the need to involve the underlying class unsafe

unsafe categories: Java can not directly access the underlying operating system, but be accessible by the local method. Unsafe class provides atomic-level hardware operations

Here is a description of atomic operations blog

https://my.oschina.net/xinxingegeya/blog/499223

There blog to explain the unsafe category

http://www.cnblogs.com/mickole/articles/3757278.html

 1 public class Counter{
 2     private Lock lock = new Lock();
 3     private int count = 0;
 4     public int inc(){
 5         lock.lock();
 6         this.count++;
 7         lock.unlock();
 8         return count;
 9     }
10 }

Non-reentrant lock


Designed as follows:

 1 public class Lock{
 2     private boolean isLocked = false;
 3     public synchronized void lock() throws InterruptedException{
 4         while(isLocked){    
 5             wait();
 6         }
 7         isLocked = true;
 8     }
 9     public synchronized void unlock(){
10         isLocked = false;
11         notify();
12     }
13 }

In fact, this is not reentrant lock, for example

 1 public class Count{
 2     Lock lock = new Lock();
 3     public void print(){
 4         lock.lock();
 5         doAdd();
 6         lock.unlock();
 7     }
 8     public void doAdd(){
 9         lock.lock();
10         //do something
11         lock.unlock();
12     }
13 }

When you call print () method, to obtain a lock, then it can no longer call doAdd () method, then you must release it before calling, so call this lock is not reentrant lock, also called a spin lock.

Reentrant lock


Designed as follows:

 1 public class Lock{
 2     boolean isLocked = false;
 3     Thread  lockedBy = null;
 4     int lockedCount = 0;
 5     public synchronized void lock()
 6             throws InterruptedException{
 7         Thread thread = Thread.currentThread();
 8         while(isLocked && lockedBy != thread){
 9             wait();
10         }
11         isLocked = true;
12         lockedCount++;
13         lockedBy = thread;
14     }
15     public synchronized void unlock(){
16         if(Thread.currentThread() == this.lockedBy){
17             lockedCount--;
18             if(lockedCount == 0){
19                 isLocked = false;
20                 notify();
21             }
22         }
23     }
24 }

Relatively speaking, reentrant means: a thread can enter any locks a block of code that the thread has already synchronized with the

The first thread execution print () method to obtain a lock, the lockedBy equal to the current thread, that thread of execution of this method to get this lock, the implementation of add () method, the same must first obtain a lock (ie, call lock.lock ()), the condition is not satisfied because of the while loop (isLocked (= true, because the thread calls the print () method of the lock is obtained when a); however, where the non-reentrant lock is a distinction lockedBy ( which means that now the thread holding the lock); because the call to add () method is invoked and print () is the same thread), that is, do not wait to continue, at this time lockedCount variable, which is currently acquired lock number plus one, when the release of all locks (that was the number of calls unlock the lock to get the number), before the implementation of notify ().

If in the implementation of this method, there is a second thread wants to implement this method, because lockedBy not equal to the second thread, the thread leads into the circulation, which is waiting (blocked), continue to execute wait () method. Only when the first thread releases all locks (ie how many times a thread calls the lock () method of how many times you have to unlock () method releases the lock call), the implementation of the notify () method, only the second thread to be out of the loop, continue.

This is reentrant lock features.

Reentrant and non-reentrant lock latch contrast, is simply: multiple reentrant locks two attributes (1, the lock thread is obtained; 2, the number of lock acquisitions), according to the first attribute judgment, If that thread holds the lock again lock, will not be blocked (wait), but the number of locked-plus-one (means that the thread has a lock (re-entry)), only the number of the thread unlock the number of completions locked (ie, the second property is equal to 0), will wake up other threads.

java commonly used reentrant lock

synchronized

java.util.concurrent.locks.ReentrantLock


other

Lock First we mentioned here, is the required block of code, resources, or data locked in their time of operation allows only one thread to do the operation. The end result is to ensure the correctness of the results cpu.

Understanding of the non-reentrant lock:

public class Test{
     Lock lock = new Lock();
     public void methodA(){
         lock.lock();
         ...........;
         methodB();
         ...........;
         lock.unlock();
     }
     public void methodB(){
         lock.lock();
         ...........;
         lock.unlock();
     }
}

When A method acquire lock lock to lock the period of time required to do B atomicity operation , if this method B and need a lock to do atomic operations, so A method it will go with the B method deadlock. Reentrant this case there will be a lock problem, called non-reentrant lock.

A method for executing the method need to wait to unlock B, but method B want to execute and complete the code must lock lock to lock. A front latch is unlocked, the other code blocks can not be used to lock the lock. This is determined by the non-reentrant lock.

So we usually need to have re-entrant needs a lock! ! ! ! A method such as atomic operations, but it has atomic operations need to call the B method, they are fighting for the same critical resources, requiring the same lock to lock (ps: competition for the same resources is the essence of critical competition for the same lock)

Reference article:
https://www.cnblogs.com/xdyixia/p/9383388.html
https://blog.csdn.net/qq_29519041/article/details/86583945
https://www.cnblogs.com/dj3839/p /6580765.html

Published 107 original articles · won praise 14 · views 40000 +

Guess you like

Origin blog.csdn.net/belongtocode/article/details/103344176