In the previous article, Mutex is an exclusive lock. Only one thread can own the lock, and it is the same thread immediately. If a Mutex is already held, it will still block the attempt to obtain the lock again. Sometimes we need to lock the same thread as the Java synchronized to re-enter, as long as it already has the lock, instead of blocking it. We can transform the implementation of Mutex in the previous article to implement a reentrant lock-ReentrantLock. This requires ReentrantLock to record the owner (thread) of the current lock, and set an integer variable to record the number of times the current thread enters.
- Public ClassReentrantLockImplementsSync {
- Protected ThreadOwner _ =Null;
- Protected LongHolds _ = 0;
- //......
- }
When obtaining and releasing a lock, first determine whether the thread is the lock owner. If the current thread already owns the lock, increase 1 at each acquire (), and decrease 1 at release () to 0, this indicates that the current owner of the lock has completely released the lock and no longer owns the lock. Therefore, set the owner to null. If the current thread is not the lock owner, wait () will be locked in an attempt to obtain the lock. In the release () method, if the owner has completely released the lock, the owner will be cleared, and y () Other threads.
- Public VoidAcquire ()Throws InterruptedException{
- If(Thread. Interrupted ())Throw New InterruptedException();
- ThreadCaller =Thread. CurrentThread ();
- Synchronized(This){// Synchronize on this
- If(Caller = owner _)
- ++ Holds _;
- Else{
- Try{
- While(Owner _! =Null) Wait ();
- Owner _ = caller;
- Holds _ = 1;
- }
- Catch(InterruptedExceptionEx ){
- Notify ();
- ThrowEx;
- }
- }
- }
- }
- Public Synchronized VoidRelease (){// Synchronize on this
- If(Thread. CurrentThread ()! = Owner _)
- Throw New Error("Illegal Lock usage ");
- If(-- Holds _ = 0 ){
- Owner _ =Null;
- Notify ();
- }
- }
Note that the above code needs to synchronize owner _ and holds _ on this to solve the Race Condition on these two variables. The attempt () method is similar to Mutex, and the check and count of the lock owner are also added:
- Public BooleanAttempt (LongMsecs)Throws InterruptedException{
- If(Thread. Interrupted ())Throw New InterruptedException();
- ThreadCaller =Thread. CurrentThread ();
- Synchronized(This){
- If(Caller = owner _){
- ++ Holds _;
- Return True;
- }
- Else If(Owner _ =Null){
- Owner _ = caller;
- Holds _ = 1;
- Return True;
- }
- Else If(Msecs <= & nb