Reentrantlock code profiling-reentrantlock. Unlock

Source: Internet
Author: User

Next let's take a look at reentrantlock. unlock: Try to subtract 1 from the lock count of the current lock, that is, the State value, and lock adds 1 to the lock count each time. This is why the lock and unlock must appear in pairs, otherwise, the lock count cannot be restored to 0, and other threads cannot try to obtain the lock.

Reentrantlock. Unlock () /**
* Attempts to release this lock.
*
* <P> if the current thread is the holder of this lock then the hold
* Count is decremented. If the Hold count is now zero then the lock
* Is released. If the current thread is not the holder of this
* Lock then { @ Link Illegalmonitorstateexception} is thrown.
*
* @ Throws Illegalmonitorstateexception if the current thread does not
* Hold this lock
*/
Public   Void Unlock (){
Sync. Release ( 1 );
}

Abstractqueuedsynchronizer. Release (INT Arg)The method deducts Arg from the number of locks. If the number of new locks is 0, the lock is released by the current thread, Attempt to wake up the next thread in the waiting queue. Note that this is only wake-up, rather than giving the lock ownership to the next thread. Whether the thread can successfully obtain the lock depends on luck.

 

Abstractqueuedsynchronizer. Release (INT Arg) /**
* Releases in exclusive mode. Implemented by unblocking one or
* More threads if { @ Link # Tryrelease} returns true.
* This method can be used to implement method { @ Link Lock # unlock }.
*
* @ Param Arg the release argument. This value is conveyed
*{ @ Link # Tryrelease} but is otherwise uninterpreted and
* Can represent anything you like.
* @ Return The value returned from { @ Link # Tryrelease}
*/
Public   Final   Boolean Release ( Int Arg ){
If (Tryrelease (ARG )){
Node H = Head;
/* If the waitstatus of the head is not zero, it indicates that its successor is waiting to wake up,
Remember the waitstatus operation in abstractqueuedsynchronizer. shouldparkafterfailedacquire? Waitstatus! = 0 indicates that it is in the cancel status, or set signal to indicate that the next thread is waiting for it to wake up. The cancel status is not analyzed here, so it can be considered here! = 0 indicates the Signal Status */
If (H ! =   Null   && H. waitstatus ! =   0 )
Unparksuccessor (h );
Return   True ;
}
Return   False ;
}

TryreleaseDefined in the sync class

Sync. tryreleaseThe number of locks to be released is subtracted from the current lock status. If the lock status is zero, the current lock thread is set to null and true is returned. Otherwise, false is returned.

In addition, the system checks whether the lock-occupying thread is being called. If not, it throws illegalmonitorstateexception.

 

Sync. tryrelease (INT releases)
Protected   Final   Boolean Tryrelease ( Int Releases ){
Int C = Getstate () - Releases;
If (Thread. currentthread () ! = Getexclusiveownerthread ())
Throw   New Illegalmonitorstateexception ();
Boolean Free =   False ;
If (C =   0 ){
Free =   True ;
Setexclusiveownerthread ( Null );
}
Setstate (C );
Return Free;
}

Next let's look at unparksuccessor.

 

Abstractqueuedsynchronizer. unparksuccessor (node) /**
* Wakes up node's successor, if one exists.
*
* @ Param Node the node
*/
Private   Void Unparksuccessor (node ){
/*
* Try to clear status in anticipation of signalling. It is
* OK if this fails or if status is changed by waiting thread.
*/
// If the current node waitstatus is set to signal, it is cleared.
Compareandsetwaitstatus (node, node. signal, 0 );

/*
* Thread to unpark is held in successor, which is normally
* Just the next node. But if canceled or apparently null,
* Traverse backwards from tail to find the actual
* Non-canceled successor.
*/
// If the subsequent node is empty or has been cancel, the first waitstatus <= 0 in the queue is found from the end, that is, the node that has not been cancel.
Node s = Node. Next;
If (S =   Null   | S. waitstatus >   0 ){
S =   Null ;
For (Node T = Tail; t ! =   Null   && T ! = Node; t = T. Prev)
If (T. waitstatus <=   0 )
S = T;
}
If (S ! =   Null )
Locksupport. unpark (S. Thread );
}

Let's look back at abstractqueuedsynchronizer. acquirequeued. Comments 1, 2, 3, and 4 indicate the execution sequence after the thread is awakened.

Abstractqueuedsynchronizer. acquirequeued (final node, int Arg) /**
* Acquires in exclusive uninterruptible mode for thread already in
* Queue. Used by condition wait methods as well as acquire.
*
* @ Param Node the node
* @ Param Arg the acquire argument
* @ Return { @ Code True} if interrupted while waiting
*/
Final   Boolean Acquirequeued ( Final Node node, Int Arg ){
Try {
Boolean Interrupted =   False ;
For (;;){
// 2 because the waiting queue will only be inserted from the end, no new waiting node will be added between the Awakened node and the header node, and only the node will be cancel
// 3. If the wake-up node is not directly followed by the first nodeAlgorithmIt can ensure that there is no waitstatus <= 0 between the node and the header node, but there may be a node whose waitstatus is greater than 0, that is, the node whose waitstatus is cancel. See note 4
// 5. If the lock is obtained successfully, the current node is set as the header node and returned. Otherwise, the thread continues to be disabled until the next wake-up attempt.
Final Node P = Node. predecessor ();
If (P = Head && Tryacquire (ARG )){
Sethead (node );
P. Next =   Null ; // Help GC
Return Interrupted;
}
// 1 is awakened by lock. Release. parkandcheckinterrupt returns false and continues to return to the for loop.
// 4. The cancel node will be cleared in shouldparkafterfailedacquire. The current node will become the direct successor of the header node, and then return false. In the next loop, you can try to obtain the lock.
If (Shouldparkafterfailedacquire (p, node) &&
Parkandcheckinterrupt ())
Interrupted =   True ;
}
} Catch (Runtimeexception ex ){
Cancelacquire (node );
Throw Ex;
}
}

 

 

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.