[JDK] JDK source code analysis -AbstractQueuedSynchronizer (1)

Outline

 

The foregoing " JDK source code analysis -Lock & Condition " brief analysis of the Lock interface, implementation class in the JDK mainly ReentrantLock (can be translated as "reentrant lock"). ReentrantLock implementation depends Sync a nested class inside thereof, and also inherited from AbstractQueuedSynchronizer Sync (referred to as the AQS). Moreover, not only ReentrantLock, complicated by a number of other tools such as CountdownLatch, CyclicBarrier, etc., are also based on the realization AQS class. AQS can be understood as the cornerstone and contracting in many classes. Therefore, prior to analysis and contract implementation principle commonly used in the class, it is necessary to understand how the AQS, time after re-analysis will be a lot simpler.

 

AQS inner core has a variable State; In addition, Node class node maintains two queues: a main queue (main queue) queue and conditions (condition queue), for simplicity, respectively, may be understood both as single doubly-linked list and .

 

AQS provides a device like a set of infrastructure, such as other commonly used classes ReentrantLock, CountdownLatch and other internal nested class Sync, all developed their own "rules of the game" on the infrastructure provided by AQS, and then produce the different products. And they are the rules of the game and the two queues operate around the state variables.

 

PS: As more AQS content, and therefore intends to analyze points articles, article first overview of its whole.

 

Code Analysis

 

AQS class signature:

public abstract class AbstractQueuedSynchronizer
    extends AbstractOwnableSynchronizer
    implements java.io.Serializable {}
It can be seen is an abstract class, it can not be instantiated directly. Major code AbstractOwnableSynchronizer its parent as follows:
public abstract class AbstractOwnableSynchronizer
    implements java.io.Serializable {

    /**
     * The current owner of exclusive mode synchronization.
     */
    private transient Thread exclusiveOwnerThread;
    
    // 其他代码
}

Its main internal maintains a variable exclusiveOwnerThread, Owner role is to mark a thread in exclusive mode, and then later when it comes to the analysis.

 

Nested Class

 

AQS has two internal nested classes, respectively, and Node ConditionObject.

Node class code as follows:

static  Final  class the Node {
     // shared mode 
    static  Final the Node the SHARED = new new the Node ();
     // exclusive mode 
    static  Final the Node EXCLUSIVE = null ; 
    
    // several states waitStatus the 
    static  Final  int CANCELED =. 1 ;
     static  Final  int the SIGNAL = - . 1 ;
     static  Final  int CONDITION = -2 ;
     static  Final  int PROPAGATE = -3 ;
     volatile  int waitStatus;

    // predecessor node (master queue) 
    volatile the Node PREV;
     // successor nodes (primary queue) 
    volatile the Node Next;
     // thread node 
    volatile the Thread Thread;
     // successor nodes (Condition queue) 
    the Node nextWaiter; 

    Final  Boolean isShared () {
         return nextWaiter == the SHARED; 
    } 

    Final the Node the predecessor () throws a NullPointerException { 
        the Node P = PREV;
         IF (P == null )
             the throw  new new a NullPointerException ();
         the else
            return p;
    }

    Node() {    // Used to establish initial head or SHARED marker
    }
    Node(Thread thread, Node mode) {     // Used by addWaiter
        this.nextWaiter = mode;
        this.thread = thread;
    }

    Node(Thread thread, int waitStatus) { // Used by Condition
        this.waitStatus = waitStatus;
        this.thread = thread;
    }
}

Added to the main queue using a second constructor, Node class can be understood as the package of thread Thread. Thus, in the main queue in the queue as a node it will be appreciated that there is one mode (MODE), stateful (waitStatus) threads.

 

Nested Class ConditionObject:

public class ConditionObject implements Condition, java.io.Serializable {
    /** First node of condition queue. */
    private transient Node firstWaiter;
    
    /** Last node of condition queue. */
    private transient Node lastWaiter;
    // ...
}

Condition ConditionObject implements the interface, which is the main operating conditions of the queue, here only class signature affixed to its head and tail nodes, particularly when used again later analysis.

 

The main variables

 

AQS code is long, but it does not have much of member variables, as follows:

// master node queue head 
Private  transient  volatile the Node head; 

// main queue tail node 
Private  transient  volatile the Node tail; 

// state, to maintain a core variable AQS 
Private  volatile  int State;

Wherein the main head and tail queue head and tail nodes, the core of AQS variable state maintenance, and the like of ReentrantLock class class implements Sync, the respective functions are achieved by the operation state.

 

CAS operation

 

Internal AQS achieve a series of CAS (Compare And Swap) operation (CAS no longer explain concepts herein may be understood own search) by Unsafe categories:

// Get Unsafe Examples 
Private  static  Final Unsafe the unsafe = Unsafe.getUnsafe ();
 // memory offset state, head, tail address variables 
Private  static  Final  Long stateOffset;
 Private  static  Final  Long headOffset;
 Private  static  Final  Long tailOffset;
 Private  static  Final  Long waitStatusOffset;
 Private  static  Final  Long nextOffset;
 static {
     the try { 
        stateOffset = unsafe.objectFieldOffset
            (AbstractQueuedSynchronizer.class.getDeclaredField("state"));
        headOffset = unsafe.objectFieldOffset
            (AbstractQueuedSynchronizer.class.getDeclaredField("head"));
        tailOffset = unsafe.objectFieldOffset
            (AbstractQueuedSynchronizer.class.getDeclaredField("tail"));
        waitStatusOffset = unsafe.objectFieldOffset
            (Node.class.getDeclaredField("waitStatus"));
        nextOffset = unsafe.objectFieldOffset
            (Node.class.getDeclaredField("next"));
    } catch (Exception ex) { throw new Error(ex); }
}

// 一些 CAS 操作
private final boolean compareAndSetHead(Node update) {
    return unsafe.compareAndSwapObject(this, headOffset, null, update);
}

private final boolean compareAndSetTail(Node expect, Node update) {
    return unsafe.compareAndSwapObject(this, tailOffset, expect, update);
}

private static final boolean compareAndSetWaitStatus(Node node,
                                                     int expect,
                                                     int update) {
    return unsafe.compareAndSwapInt(node, waitStatusOffset,
                                    expect, update);
}

private static final boolean compareAndSetNext(Node node,
                                               Node expect,
                                               Node update) {
    return unsafe.compareAndSwapObject(node, nextOffset, expect, update);
}

Many of AQS operation of the internal thread safety is achieved through the CAS.

 

summary

 

1. AQS is an abstract class that can not be instantiated directly;

2. AQS inner core maintains a variable state, as well as two queues: a main queue (main queue) queue and conditions (condition queue);

3. AQS provides a set of infrastructure, ReentrantLock AQS and other classes are usually inherited by nested inside a class Sync, and to develop their own "rules of the game" in the Sync class.

 

This article only provides an overview AQS, then followed a detailed analysis of implementation principle. In addition, there is a class AbstractQueuedLongSynchronizer, which is substantially identical with AQS, except that it is the state variable type long int and the type of AQS, not analyzed separately.

 

PS: There are several articles written also good at the following link:

https://www.cnblogs.com/liuyun1995/p/8400663.html

 

 

Stay hungry, stay foolish.

PS: This article first appeared in the public micro-channel number] [WriteOnRead.

Guess you like

Origin www.cnblogs.com/jaxer/p/11297652.html