当前位置:网站首页>12. AQS of abstractqueuedsynchronizer

12. AQS of abstractqueuedsynchronizer

2022-06-11 12:14:00 Shixiaozan

1、 Pre knowledge

Fair and non-fair locks

Reentrant lock

spinlocks

LockSupport

Linked list of data structures

Template design pattern of design pattern

2、 What is it?

2.1、 Literally

Abstract queue synchronizer

Source code

 

AbstractOwnableSynchronizer 

AbstractQueuedLongSynchronizer 

AbstractQueuedSynchronizer                   Usually :AbstractQueuedSynchronizer Referred to as AQS 

2.2、 Technical explanation

Is used to build locks or other synchronizer components The heavyweight infrastructure and the whole JUC The cornerstone of the system , Through the built-in FIFO queue To complete the queuing work of the resource acquisition thread , And through a int Class variables Indicates the state of holding the lock

 

CLH:Craig、Landin and Hagersten queue , It's a one-way list ,AQS The queue in is CLH Virtual two-way queues for variants FIFO 

3、AQS Why JUC The most important cornerstone of content

3.1、 and AQS Relevant

 

ReentrantLock

 

CountDownLatch

 

ReentrantReadWriteLock

 

Semaphore

 

......

3.2、 Further understand the relationship between lock and synchronizer

lock , For lock users

It defines the use layer of programmer and lock interaction API, Hidden implementation details , You can call .

synchronizer , Lock oriented implementers

such as Java Concurrent God DougLee, A unified specification is proposed and the implementation of lock is simplified ,

The synchronization state management is blocked 、 Blocking thread queuing and notification 、 Wake up mechanism, etc .

4、 What can I do?

4.1、 Locking can cause blocking

If there is a jam, you need to line up , Queue is necessary to realize queuing

4.2、 interpretative statement   

The thread that grabs the resource directly processes the business , Those who can't grab resources must involve a kind of Queuing mechanism  . Threads that fail to preempt resources continue to wait ( Similar banking business processing windows are full , Customers who do not have an acceptance window can only go to Wait in line in the waiting area  ), However, the waiting thread still retains the possibility of acquiring locks, and the process of acquiring locks continues ( Customers in the waiting area are also waiting for a call , It's time to go to the reception window to handle business ). 

  

Now that we're here Queuing mechanism , Then there must be some kind of formation , What data structure is such a queue ? 

 

If shared resources are occupied ,  A certain blocking waiting wake mechanism is needed to ensure lock allocation  . The main use of this mechanism is CLH A variant of the queue implements , Add the thread that can't get the lock temporarily to the queue , This queue is AQS The abstract expression of . It encapsulates threads that request shared resources as nodes of the queue ( Node ), adopt CAS、 Spin and LockSupport.park() The way , maintain state The state of the variable , Make concurrency synchronous . 

 

5、AQS preliminary

5.1、AQS First time to know

Website to explain

 

If there is a jam, you need to line up , Queue is necessary to realize queuing

AQS Use one volatile Of int Member variables of type to represent the synchronization state , Through the built-in FIFO Queue to complete the queuing work of resource acquisition, encapsulate each thread to preempt resources into a Node Node to achieve lock allocation , adopt CAS Finish right State Value modification .

 

5.2、AQS Internal architecture

 

5.2.1、AQS Oneself

AQS Of int Variable

AQS The synchronization state of State Member variables

 

The acceptance window status of the bank's business processing

Zero means no one , Free state can handle

Greater than or equal to 1, Someone is occupying the window , Wait

AQS Of CLH queue

CLH queue ( The names of the three cows make up ), For a two-way queue

 

Waiting customers in the waiting area of the bank

A small summary

If there is a jam, you need to line up , Queue is necessary to realize queuing

state Variable +CLH deque

3.5.2、 Inner class Node(Node Class in AQS Intra class )

Node Of int Variable

Node Waiting state waitState Member variables

volatile int waitStatus

vernacular

Other customers in the waiting area ( Other threads ) Waiting state

Each individual in the queue is a Node

Node This kind of explanation

internal structure

static final class Node{

    // share 

    static final Node SHARED = new Node();

    

    // Monopoly 

    static final Node EXCLUSIVE = null;

    

    // The thread has been cancelled 

    static final int CANCELLED = 1;

    

    // Subsequent threads need to wake up 

    static final int SIGNAL = -1;

    

    // wait for condition Wake up the 

    static final int CONDITION = -2;

    

    // Shared synchronous state acquisition will propagate unconditionally 

    static final int PROPAGATE = -3;

    

    //  For the initial 0, The states are the above 

    volatile int waitStatus;

    

    //  Front node 

    volatile Node prev;

    

    //  The subsequent nodes 

    volatile Node next;


    //  At present Node Threads 

    volatile Thread thread;

    // Point to the next in CONDITION  Nodes of state 

    Node nextWaiter;

    // ...

    

Attribute specification

 

5.3、AQS The basic structure of synchronization queue

 

CLH:Craig、Landin and Hagersten queue , It's a one-way linked list ,AQS The queue in is CLH Virtual two-way queues for variants (FIFO) 

6、 From our ReentrantLock Start reading AQS

Large drawing description AQS Source code interpretation _ Shixiaozan's blog -CSDN Blog

Lock Implementation class of interface , Basically through 【 polymerization 】 One. 【 Queue synchronizer 】 The subclass of completes the thread access control

ReentrantLock Principle

 

From the simplest lock Methods start to look at fairness and unfairness

 

 

 

It can be clearly seen that fair lock and unfair lock lock() The only difference of the method is that the fair lock has a restriction when it obtains the synchronization state :

hasQueuedPredecessors() 

hasQueuedPredecessors It is a method to judge whether there is an effective node in the waiting queue when a fair lock is applied  

Unfair lock up , Method lock()

Compare the of fair lock and unfair lock tryAcquire() Method implementation code , The difference is When an unfair lock obtains a lock, there is one less judgment than in a fair lock !hasQueuedPredecessors() 

  

hasQueuedPredecessors() To determine whether to queue up , The differences between fair locks and unfair locks are as follows : 

  

Fair lock : Fair lock pays attention to first come, first served , When a thread acquires a lock , If there is already a thread waiting in the waiting queue of this lock , Then the current thread will enter the waiting queue ; 

  

Not fair lock : Whether there is a waiting queue or not , If you can get the lock , Then immediately occupy the lock object . That is to say, the first queue thread of the queue is unpark(), After that, you still need to compete for the lock ( In case of thread contention ) 

 

Source code interpretation starts

lock()

 

acquire() Source code and 3 The big process is going to

 

 

tryAcquire(arg) This time, the lock is not fair

 

next step : 

 

nonfairTryAcquire(acquires)

 

return false; Continue to advance the conditions , Next step

return true; end

addWaiter(Node.EXCLUSIVE)

addWaiter(Node mode)

 

enq(node);

 

In a two-way list , The first node is a virtual node ( Also known as sentinel node ), It doesn't store any information , It's just occupation .

The real first node with data , It starts with the second node .

If 3 Number ThreadC The thread in

prev

compareAndSetTail

next

acquireQueued(addWaiter(Node.EXCLUSIVE), arg)

acquireQueued

 

If you fail again, you will enter

shouldParkAfterFailedAcquire and parkAndCheckInterrupt In the method

 

shouldParkAfterFailedAcquire 

If the precursor node's waitStatus yes SIGNAL state , namely shouldParkAfterFailedAcquire Method will return true The program will continue to go down parkAndCheckInterrupt Method , Used to suspend the current thread

 

parkAndCheckInterrupt 

 

unlock->sync.release(1);->tryRelease(arg)->unparkSuccessor

原网站

版权声明
本文为[Shixiaozan]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/162/202206111207398505.html