Chapter 6 ReentrantLock source code parsing 2 -- release Lock unlock (), reentrantlock2 --

Source: Internet
Author: User

Chapter 6 ReentrantLock source code parsing 2 -- release Lock unlock (), reentrantlock2 --

The most common method:

Int a = 12; // Note: This is usually set to a class variable, for example, the segment lock in the Segement and the global lock final ReentrantLock lock in the copyOnWriteArrayList = new ReentrantLock (); lock. lock (); // get the lock try {a ++; // business logic} catch (Exception e) {} finally {lock. unlock (); // release the lock}

NOTE: For the source code parsing of the lock () method, refer to "Chapter 5 ReentrantLock source code parsing 1 -- obtain unfair lock and fair lock ()". The specific link is as follows:

Http://www.cnblogs.com/java-zhao/p/5131544.html

 

Release lock: unlock ()

Steps:

1) obtain the current number of locks, then use the number of locks minus the number of locks (1 here), and finally obtain the result c.

2) checks whether the current thread is an exclusive lock thread. If not, an exception is thrown.

3) If c = 0, the lock is successfully released, the current exclusive thread is set to null, the number of locks is set to 0, and true is returned.

4) if c! = 0 indicates that the lock failed to be released. If the number of locks is set to c, false is returned.

5) if the lock is released successfully, wake up a non-canceled node closest to the first node.

Source code:

ReentrantLock: unlock ()

/*** Release the lock ** 1) if the current thread holds the lock, the number of locks is decreased * 2) if the number of locks is decreased to 0, the lock is released. * If the current thread does not have a persistent lock, an exception is thrown */public void unlock () {sync. release (1 );}View Code

AbstractQueuedSynchronizer: release (int arg)

/*** Release lock (in exclusive mode) */public final boolean release (int arg) {if (tryRelease (arg )) {// if the lock Node is successfully released h = head; // get the first Node :( Note: The first Node here is the Node currently releasing the lock) if (h! = Null & h. waitStatus! = 0) // the header node exists and the waiting state is not to cancel unparkSuccessor (h); // wake up a non-canceled node closest to the header node and return true;} return false ;}View Code

Sync: tryRelease (int releases)

/*** Release lock */protected final boolean tryRelease (int releases) {int c = getState ()-releases; // obtain the current number of locks-the number of incoming locks (1 here) if (Thread. currentThread ()! = GetExclusiveOwnerThread () // The current thread does not hold the lock throw new IllegalMonitorStateException (); boolean free = false; if (c = 0) {// The lock is released free = true; setExclusiveOwnerThread (null);} // if it is not 0, what should I do? Will it be released? SetState (c); return free ;}View Code

AbstractQueuedSynchronizer: unparkSuccessor (Node node)

/*** Wake up a non-canceled node closest to the first node Node * @ param node header node */private void unparkSuccessor (node Node) {int ws = node. waitStatus; if (ws <0) // set ws to 0 (that is, none) compareAndSetWaitStatus (node, ws, 0 ); /** get the Node whose next waiting status is not cancel */node s = Node. next; // if (s = null | s. waitStatus> 0) {s = null;/** Note: you can find a non-canceled node closest to the header node from the previous traversal, traversing from the back is said to be in the queue (enq (), maybe nodeX. next = null, but I didn't see it when I was reading the source code */for (Node t = Tail; t! = Null & t! = Node; t = t. prev) if (t. waitStatus <= 0) s = t;} if (s! = Null) LockSupport. unpark (s. thread); // wake up a non-canceled node closest to the header node}View Code

 

Note:

I have some questions about the program comments. I will organize them as follows:

  • If the program starting with a lock is obtained successfully, the lock will be resolved once in finally. How can this problem be solved?
  • When a non-canceled node closest to the header node is found, it is carried out from the back to the back, because "traversing from the back to the back is said to be in the queue (enq ()) nodeX. next = null ", but it is not displayed when reading the source code

Answer to the first question:

Reentrant is reflected in the following Program (lock, the most common is in recursion ):

Final ReentrantLock lock = new ReentrantLock (); public void add () {lock. lock (); // get the lock try {add (); // business logic} catch (Exception e) {} finally {lock. unlock (); // release the lock }}View Code

Note:

  • The above program is just an example. In recursive use, there must be conditions for Recursive termination.
  • Each lock () method corresponds to an unlock (). Therefore, when unlocking, you only need to set the number of passed locks to 1.

Answer to the second question:

Remember: It may be incorrect if you keep going next along the node header.
For example, A1> A2> A3
Now let's start from A1. When we get to A3, a new node, A4, enters the queue and goes down with the following code:

We can see that steps 1 and 2 are not atomic, that is, when CAS is executed but 2 is not executed, the queue is A1 --> A2 --> A4, if you use next, you may lose A3, but node. prev = t (A4.prev = A3), that is to say, the precursor node has been assigned a value. If you end the A4.prev from the queue, it will be A3, that is, A3 will not be lost.

 

Related Article

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.