Double queue

In AQS, there are two queues

  • Wait queue: Used to suspend the current thread and wait for a condition to wake up or be interrupted.
  • Synchronous queue: when multiple threads compete for locks, if there is a race, it is put into the synchronous queue, waiting to wake up and re-compete.

Wait queues are maintained in AQS.ConditionObject, while synchronous queues are maintained in AQS. Once the element in the waiting queue is woken up, it is moved to the synchronous queue, and the thread can resume execution until it recontests for the lock. The schematic code is as follows

ReentrantLock lock = new ReentrantLock();
Conditon condition = lock.newCondition();
// thread 1
void run() { try { lock.lock(); condition.await(); } catch (Exception e) {} finally {lock.unlock(); } } // thread 2 voidrun() { try { lock.lock(); condition.signal(); } catch (Exception e) {} finally {lock.unlock();} catch (Exception e) {} finally {lock.unlock(); }}Copy the code

Condition::signal -> Condition::doSignal -> AQS::transferForSignal In Condition::doSignal, the awakened thread is removed from the wait queue.

Node

The inner class Node of AQS is the core data structure. Wait queue and synchronization queue are implemented by it, which can be simplified as

class Node { Node nextWaiter; // The value can be SHARED, EXCLUSIVE intwaitStatus; // CANCELLED SIGNAL CONDITION PROPAGATE Node prev; // Bidirectional linked list, pointing to the previous element Node next; // Two-way linked list, pointing to the next element}Copy the code

state

State is highly extensible in AQS and represents multiple states as an int in different implementations

  • In CountDownLatch, state represents the number of counts remaining. Is 0, end.
  • In Semaphore, state represents the number of remaining licenses.
  • In ReentrantLock, state indicates the lock occupation status. 0 indicates preemption, and greater than 0 indicates non-preemption. It also indicates the number of reentrants.
  • In ReentrantReadWriteLock, 16 bits lower in state indicates a write lock, and 16 bits higher in state indicates a read lock. Synchronization queues hold threads competing for read locks.

Open interface

In my opinion, the extensibility of AQS lies in its synchronous queue and State. One is used to store resource competitors and one is used to identify the available status of the resource. At present the understanding is very superficial, if there is a mistake, hope not stingy give advice.