AQS: full name is AbstractQueuedSynchronizier, abstract queue synchronization; It is the basis for various synchronization tool locks, such as ReentrantLock and CyclicBairier, which are based on AQS.

CAS

Take AtomicInteger as an example to analyze the application of CAS. First look at the internal structure:






































public static class AtomicBTreePartition{ private volatile long lock; private static final AtomicLongFieldUpdater<AtomicBTreePartition> lockFieldUpdater =AtomicLongFieldUpdater .newUpdater(AtomicBTreePartition.class,"lock"); public void acquireLock(){ long t = Thread.currentThread().getId(); while (! LockFieldUpdater.com pareAndSet (this, 0, 1)) {/ / database operations}} public void releaseLock () {}}Copy the code








AQS

Her core consists of three parts.

The following uses ReentrantLock’s unfair lock as an example to analyze its lock and lock release implementation. Lock operation code:

  public void lock() {
        sync.acquire(1);
    }Copy the code

Follow up:

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

Lock acquisition operations for unfair locks:

final boolean nonfairTryAcquire(int acquires) { final Thread current = Thread.currentThread(); int c = getState(); If (c == 0) {if (compareAndSetState(0, acquires)) {if (compareAndSetState(0, acquires)) { SetExclusiveOwnerThread (current) Return true; } else if (current == getExclusiveOwnerThread()) {if (current == getExclusiveOwnerThread()) {int nexTC = c + acquires; if (nextc < 0) // overflow throw new Error("Maximum lock count exceeded"); setState(nextc); return true; } return false; }Copy the code

Queue competition:

final boolean acquireQueued(final Node node, int arg) { boolean interrupted = false; try { for (;;) {// loop final Node p = node.predecessor(); If (p == head && tryAcquire(arg)) {// If (p == head && tryAcquire(arg)) {// If (p == head && tryAcquire(arg)) {// If (p == head && tryAcquire(arg)) {// If (p == head && tryAcquire(arg)); // acquire succeeds, set the new head node p.ext = null; Return interrupted; // Clear references from the previous node to the current node. } the if (shouldParkAfterFailedAcquire (p, node)) / / check whether need to park after failure interrupted | = parkAndCheckInterrupt (); } } catch (Throwable t) { cancelAcquire(node); If (interrupted) selfInterrupt(); throw t; }Copy the code

summary


This section introduces the concepts of CAS and AQS, and then uses AtomicInteger as an example to explore how atomic operations are guaranteed by CAS.

Finally, with ReentrantLock locking operations, we follow up how AQS are used to ensure different internal operations.



It is a preliminary exploration of the realization of synchronization principle.





Original is not easy, reprint please indicate the source, let us exchange, common progress, welcome communication.