A reentrant lock, also called a recursive lock, means that the inner recursive function can still acquire the lock without being affected after the same thread's outer function acquires the lock.
Both Reentrantlock and synchronized are reentrant locks in the Java environment.
[Java]public class Test implements runnable{public synchronized void get () { System.out.println ( Thread.CurrentThread (). GetId ()); Set ();} Public synchronized void Set () { System.out.println (Thread.CurrentThread (). GetId ());} @Overridepublic void Run () { get ();} public static void Main (string[] args) { Test ss=new test (); New Thread (ss). Start (); New Thread (ss). Start (); New Thread (ss). Start ();}} [/java]
Two examples The final result is correct, that is, the same thread ID is continuously output two times.
The results are as follows:
Threadid:8
Threadid:8
Threadid:10
Threadid:10
Threadid:9
Threadid:9
The biggest function of reentrant lock is to avoid deadlock
We use spin lock as an example
[Java]public class SpinLock { private atomicreference owner =new atomicreference<>; public void Lock () { Thread current = Thread.CurrentThread (); while (!owner.compareandset (null, current)) { } } publicly void Unlock () { Thread current = Thread.CurrentThread (); Owner.compareandset (current, null); }} [/java]
For spin locks,
1, if there is the same thread two times call lock (), will cause the second call to the lock position spin, resulting in deadlock
Indicates that the lock is not reentrant. (Within the lock function, you should verify that the thread is the thread that has acquired the lock)
2, if the 1 problem has been resolved, when unlock () First Call, the lock has been released. You should not actually release the lock.
(statistics are used in counting times)
After the modification, the following:
[Java]public class SpinLock1 { private atomicreference owner =new atomicreference<>; private int count =0; public void Lock () { Thread current = Thread.CurrentThread (); if (Current==owner.get ()) { count++; return; } while (!owner.compareandset (null, current)) { } }public void Unlock () { Thread current = Thread.CurrentThread (); if (Current==owner.get ()) { if (count!=0) { count--; } else{ Owner.compareandset (current, null);}}} [/java]
The spin lock is a re-entry lock.
Reentrant lock mechanism: Each lock is associated with a request counter and a thread that occupies him, when the request counter is 0 o'clock, the lock can be considered unhled, when a thread requests a unheld lock, the JVM records the lock's owner, and adds 1 to the lock request count. If the same thread requests this lock again, the request counter increases, and when the thread exits the syncronized block, the counter is reduced by 1 and the lock is released when the counter is 0 o'clock.
[Java]public class Widget {public synchronized void dosomething () {...}} public class Loggingwidget extends widgets {public synchronized void dosomething () { System.out.println ( ToString () + ": Calling dosomething"); Super.dosomething (); }} [/java]
Without the reentrant nature of the Java lock, when a thread acquires a lock on Loggingwidget's dosomething () block of code, the thread has already got the lock of the Loggingwidget, when the DoSomething () method in the parent class is called, The JVM will assume that the thread has acquired a loggingwidget lock, and cannot retrieve it again, thus failing to invoke the Widget's DoSomething () method, resulting in a deadlock. As we can see from this, Java threads are based on "per-thread (per-thread)" rather than "per-call (per-invocation)", meaning that Java assigns a lock to each thread instead of assigning a lock to each call.
Java concurrent programming-can be re-entered lock