Java JUC core AQS related sorting

May Hacker 2022-01-26 18:30:41 阅读数:506

java juc core aqs related

Preface

principle

 Insert picture description here
AQS One was maintained volatile int state( On behalf of shared resources ) And a FIFO Thread wait queue ( Multithreaded contention resources will enter this queue when they are blocked )

AQS Define two ways to share resources :Exclusive( Monopoly , Only one thread can execute , Such as ReentrantLock) and Share( share , Multiple threads can execute at the same time , Such as Semaphore/CountDownLatch).

Different custom synchronizers compete for shared resources in different ways . The custom synchronizer only needs to implement shared resources when it is implemented state How to obtain and release , As for the maintenance of specific thread waiting queue ( If you fail to get resources and join the team / Wake up and wait ),AQS It has been implemented at the top level .

State

Yes State There are three operations :

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

Node

Node Node is the encapsulation of every thread waiting to get resources , Variable waitStatus Is the current Node The waiting state of the node , share 5 Species value CANCELLED(1, Cancel scheduling )、SIGNAL(-1, The successor node is waiting for the current node to wake up )、CONDITION(-2, The node is waiting for Condition On )、PROPAGATE(-3, In sharing mode , The predecessor node will not only wake up its successor node , At the same time, it may wake up the subsequent nodes )、0

It should be noted that , A positive value indicates that the node has been cancelled , A negative value indicates that the node is in a valid waiting state , So many places in the source code >0、<0 To determine whether the state of the node is normal .

acquire(int)

In exclusive mode, the thread obtains the top-level entry of shared resources , If we get resources , Thread directly returns , Otherwise enter the waiting line , Until we get the resources

 public final void acquire(int arg) {

if (!tryAcquire(arg) &&
acquireQueued(addWaiter(Node.EXCLUSIVE), arg)){

selfInterrupt();
}
}

Yes acquire The core process of can be expressed as follows :
 Insert picture description here

addWaiter(Node)

private Node addWaiter(Node mode) {

// Construct nodes in a given pattern .mode There are two kinds of :EXCLUSIVE( Monopoly ) and SHARED( share )
Node node = new Node(Thread.currentThread(), mode);
// Try a quick way to get to the end of the team .
Node pred = tail;
if (pred != null) {

node.prev = pred;
if (compareAndSetTail(pred, node)) {

pred.next = node;
return node;
}
}
// The last step of failure is through enq The team .
enq(node);
return node;
}

enq(Node)

private Node enq(final Node node) {

//CAS" The spin ", Until I successfully joined the end of the team 
for (;;) {

Node t = tail;
if (t == null) {
 // The queue is empty , Create an empty flag node as head node , And will tail And point to it .
if (compareAndSetHead(new Node()))
tail = head;
} else {
// Normal process , Put it at the end of the line 
node.prev = t;
if (compareAndSetTail(t, node)) {

t.next = node;
return t;
}
}
}
}

release(int)

public final boolean release(int arg) {

if (tryRelease(arg)) {

Node h = head;// Find the head node 
if (h != null && h.waitStatus != 0)
unparkSuccessor(h);// Wake up the next thread in the waiting queue 
return true;
}
return false;
}

call tryRelease() To release resources . One thing to note is that , It is based on tryRelease() To determine whether the thread has finished releasing resources .

Reference resources

Java Concurrent AQS Detailed explanation

copyright:author[May Hacker],Please bring the original link to reprint, thank you. https://en.javamana.com/2022/01/202201261830387164.html