Java Concurrency Programming (2) basic structure of Abstractqueuedsynchronizer

Source: Internet
Author: User
Tags volatile

A preface

Although there have been many predecessors have analyzed abstractqueuedsynchronizer (abbreviation Aqs) class, but feel those points are always others, see again even a few times will not be impressed. So the record is more impressive, but also to discuss with you (this is the advantage of repeating the wheel, but also mainly the length of this article is too long, hesitated for a long time to decide to write). Since there are many predecessors have analyzed this class to explain how important it is, below we see the implementation of the concurrent package is clear Aqs occupies the position.

Second, the internal structure of AQS

Personal habits like to look at the internal structure first, because the internal result is the core of a class implementation. It is analyzed that: the data structure of AQS class is using doubly linked list, including head node and tail node, and head node is mainly used for subsequent scheduling. There is also a one-way linked list, which is only present if you use condition. And there may be multiple condition linked lists (where a linked list is a specific representation of a queue, so it can also be called a queue). Such as:

Three internal structure source code parsing the inheritance relationship of class 3.1

  

1, indicating that it is an abstract class, it is possible that there is an abstract method requires subclasses to rewrite the implementation (specifically, which methods need to rewrite the following instructions).

2, it also inherits the Abstractownablesynchronizer (AOS) class can set exclusive resource thread and get exclusive resource thread (exclusive lock will involve, AOS source code can go inside to see).

In addition, we recommend that you look at the comments on the class, in fact, quite useful.

Inner classes of Class 3.2

Analyze the structure in the inner class first and see how Aqs refers to it. The following first look at Node.class, the main analysis is in the comments.

/*** Wait Queue node class. * Note the comment on the class, which is the first line of the original comment, which represents the wait-queued nodes class (though it is actually a doubly linked list). */Static Final classNode {/*** Total divided into two modes: shared and exclusive*/    /**nodes that are waiting in shared mode*/    Static FinalNode SHARED =NewNode (); /**nodes that are waiting in exclusive mode*/    Static FinalNode EXCLUSIVE =NULL; /*** The following several indicate the node state, which is the possible value of Waitstatus. */    /*** Flag thread is in the canceled state * The node will not change when it enters the state.    */static final int CANCELLED = 1;     /** * The thread that marks the successor node is in a wait state and needs to be undocked (that is, Wake Unpark).     * Change: When the thread of the current node releases the synchronization state or is canceled, the successor is notified of the subsequent node's thread to run. */    Static Final intSIGNAL =-1; /*** The token thread is waiting for the condition (Condition), that is, the node is in the waiting queue.     * Change: When other threads call the signal () method on condition, the node will be transferred from the wait queue to the synchronization queue and added to the synchronization state of the fetch. */    Static Final intCONDITION =-2; /*** Indicates that the next shared Sync State acquisition will be transmitted unconditionally. */    Static Final intPROPAGATE =-3; /*** Node status, which contains the above four states (there is also an initialization state of 0) * Special NOTE: It is a volatile keyword decorated to ensure its thread visibility, but not guaranteed atomicity. * So update the status, using CAS mode to update, such as: Compareandsetwaitstatus*/    volatile intWaitstatus; /*** The precursor node, such as the current node is canceled, requires a precursor node and a successor to complete the connection. */    volatileNode prev; /*** Successor node. */    volatileNode Next; /*** The current thread when entering the queue. */    volatilethread thread; /*** Store the successor nodes in the condition queue. */Node Nextwaiter; /*** Determine if shared mode*/    Final BooleanisShared () {returnNextwaiter = =GKFX; }    /*** Gets the predecessor node, throws an exception if the predecessor node is empty*/    FinalNode predecessor ()throwsnullpointerexception {Node P=prev; if(p = =NULL)            Throw NewNullPointerException (); Else            returnp; }    //omit three constructors}

Summary: When each thread is blocked, it is encapsulated into a node and placed in the queue. Each node contains the thread, State, predecessor node reference, subsequent node reference, and next waiting person for the current node.

It is also important to note that the waitstatus corresponds to the status of what the meaning of the other is not clear about the role of the volatile keyword, please go to read.

property name description
int waitstatus / The td> represents the state of the node. It contains the following states:
  1. CANCELLED, with a value of 1, indicating that the current thread is canceled, and that the node enters the state without changing.
  2. SIGNAL, a value of 1, indicates that the current node's successor contains threads that need to be run, that is, unpark; changes: When the current node's thread releases the synchronization state or is canceled, the successor is notified of the subsequent node's thread to run.
  3. CONDITION, a value of 2, that indicates that the current node is waiting for CONDITION, that is, in the CONDITION queue; change: When another thread calls the signal () method on CONDITION, The node will be transferred from the waiting queue to the synchronization queue and added to the synchronization state of the fetch. The
  4. PROPAGATE, which is 3, indicates that subsequent acquireshared in the current scene can be executed; the
  5. value is 0, indicating that the current node is in the sync queue, waiting for the lock to be acquired.
node prev
 A precursor node, such as the current node being canceled, requires a precursor node and a successor to complete the connection. 
node next
 subsequent nodes. 
thread thread
 The current thread when it is queued. 
  node Nextwaiter  
 stores the successor nodes in the condition queue.  

Then take a brief look at the source code of Conditionobject, we will analyze the role of this class separately.

/*** Implement Condition Interface*/ Public classConditionobjectImplementsCondition, java.io.Serializable {Private Static Final LongSerialversionuid = 1173984872572414699L; /*** The first node of a conditional queue. */    Private transientAbstractqueuedsynchronizer.node Firstwaiter; /*** The last node of the conditional queue. */    Private transientabstractqueuedsynchronizer.node Lastwaiter;}

From which you can see it or implement the condition interface, and what specification does the condition interface define? yourself to see:), you will not find a bit similar to some of the methods in object.

3.3 Main internal Members
    // head knot Point    Private transient volatile Node head;     // tail knot point    Private transient volatile Node tail;     // Synchronization Status    Private volatile int State;
Iv. Summary

Through the above analysis, it is clear what the internal structure is. Summary below:

  node is the basis for the sync queue and condition queue build, and the Sync Queue (node doubly linked list) is included in the Synchronizer. the Synchronizer has three member variables: the head of the sync queue, the tail node of the sync queue tail, and the status state. For lock acquisition, the request forms a node, mounts it at the tail, and the lock resource's transfer (release and fetch) starts backwards from the head. For the status state of the Synchronizer maintenance, the fetch of multiple threads to it will result in a chain-structured structure.

Java Concurrency Programming (2) basic structure of Abstractqueuedsynchronizer

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.