AQS entry

About a AQS

路径:java.util.concurrent.locks.AbstractOwnableSynchronizer。

Definitions: AQS provided a volatile modified by maintaining a state of type int and a FIFO waiting queue (bidirectional linked list implementation) to achieve the locking function frame synchronizer .

Description: the AQS queue synchronizer, an abstract class is used to build the base frame and lock synchronized similar effects (or synchronization component) is mainly used a method which is inherited, and then implement the abstract methods to maintain State, as of ReentrantLock (inner classes inheritance) is based on the realization of AQS.

Two core

Core methods: synchronous provides acquire () and release () two methods, see the name to know Italy, to obtain a synchronized state method, one is released, the key is the operating state.

public final void acquire(int arg) {
        if (!tryAcquire(arg) &&
            acquireQueued(addWaiter(Node.EXCLUSIVE), arg))
            selfInterrupt();
    }

Final Release Boolean public (int Arg) { 
        IF (tryRelease (Arg)) {// synchronization status successfully released 
            the Node H = head; 
            IF (!! = null && h.waitStatus H = 0) 
                // immediate release head node 
                unparkSuccessor ( H); 
            return to true; 
        } 
        return to false; 
    }

The main implementation method: tryAcquire (int arg) and tryRelease (int arg) which is above acquire and release the call, where we need to complete the implementation. tryAcquire (int arg) is to obtain the state, to change his value, tryRelease (int arg) Here is the release state.

 

AQS class structure:

 

 

 

 

 

Key members of Figure 1

1: state, this is the competition for resources between threads, also known as synchronization status can change his value means acquire or release the lock.

CAS provides three operations to manipulate the synchronization status

  • getState()
  • setState()
  • compareAndSetState()

 

2: Node head Node tail and head point node and the end node for the operation of a doubly linked list.

3: inner class Node, a doubly linked list of nodes, in fact, doubly linked list to achieve Node which sets a reference to the two Node

Final the Node class {static 
  the Node Next; next node
  Node pre; previous node 
  Thread thread; current thread
  int waitState; node current state of the node, and the above said synchronization state state independent.
  Node nextWaiter; said rear
}

4: INNER ConditionObject, for synchronizing the operation of the waiting queue, the queue is equivalent synchronized with the Object of wait () and Notify (), and is used aqs ConditionObject object.

 

Three: Integration

1: A first call will go to the thread execution acquire () This method, if tryAcquire () can obtain state (cas change value), it means to acquire the lock, then you can execute the code directly to the A's.

If it fails, it will create a Node, to which the current thread A set in the tail end of the chain nodes. Followed by a period of spin to try to acquire the lock, until the current node before the node waitState is a pre specified state (-1), a thread is Park () This thread is suspended. So you do not have a spin, off-hold or a being interrupted, either in front of the node release, there will be a wake-up operation unpark behind node. I described here is very simple, but very complex, going to see the source code, reference to other https://www.cnblogs.com/iou123lg/p/9464385.html

public final void acquire(int arg) {
        if (!tryAcquire(arg) &&
            acquireQueued(addWaiter(Node.EXCLUSIVE), arg))
            selfInterrupt();
    }

2: a doubly linked list corresponding to the object aqs a plurality of synchronous queue and waiting queue, which is above the synchronous queue head and tail of the composition, is used to store the operating state of the synchronization; and I want to emphasize here that the waiting queue, which is It relies on this internal class ConditionObject

public class ConditionObject implements Condition
/** First node of condition queue. */
private transient Node firstWaiter;
/** Last node of condition queue. */
private transient Node lastWaiter;

 

Here you can see above Node inherited, that is also a nextWaiter field, waiting queue is a round robin list firstWaiter and lastWaiter point to the head and tail, nextWaiter points to the next structure is the case.

Waiting queue of the node is generated, a new aqs a plurality of objects can Condition object, which means to have a plurality of queue, each queue corresponds to a Condition

E.g. condition1 = new Condition (), when condition1.await ()

Node node = addConditionWaiter();
int savedState = fullyRelease(node);
int interruptMode = 0;
while (!isOnSyncQueue(node)) {
LockSupport.park(this);
if ((interruptMode = checkInterruptWhileWaiting(node)) != 0)
break;
}

First creates a Node node into condition1 of the list based on the current thread, let lastWaiter and firstWaiter point to her.

Then I will go to free up resources, the release state, make a reduction operation. Here the release of resources, the first node in the synchronous queue means to be removed, and wakes up the back of the node.

Followed by a period of self-loop, it determines that the node determines whether there is synchronization queue, if not, then suspends the current thread. If you have to re-compete for state. Normally this new waiting queue node is not present in the synchronization queue, it will be suspended, unless the call signal () method, the equivalent notify Object ()

signal()

This method will go condition1 waiting queue firstWaiter out (that is, delete), and then he added synchronization queue is moved to the end of the synchronous queue from the head of the queue of waiting.

 

Borrowing:

https://www.cnblogs.com/iou123lg/p/9464385.html

https://www.jianshu.com/p/da9d051dcc3d

 



   

 

Guess you like

Origin www.cnblogs.com/xlblog/p/11575433.html
AQS
AQS