This is the 10th day of my participation in the August More Text Challenge. For details, see:August is more challenging
preface
AbstractQueuedSynchronizer abstract queue type synchronizer, AQS defines a set of synchronizer framework for multithreaded access to a Shared resource. Most synchronization classes in JUC are implemented according to AQS.
1. The principle of AQS
AQS is an abstract class, which is used mainly through inheritance. It does not implement any interface itself, but only defines methods for obtaining and releasing synchronization state.
Main principles:
The core idea of AQS is that if the requested shared resource is idle, then the current thread requesting the resource is set to a valid worker thread and the shared resource is set to a locked state. If the shared resource is occupied, some blocking waiting mechanism is required to ensure that the lock is allocated.
CLH: Craig, Landin and Hagersten queues are unidirectional linked lists. Queues in AQS are virtual bidirectional queues (FIFO) of CLH variants. AQS implements lock allocation by encapsulating each thread requesting a shared resource into a node.
1.1 AbstractOwnableSynchronizer
This class is relatively simple to set and acquire the owner thread of an exclusive lock
1.2 AbstractQueuedSynchronizer
1.2.1 Main data structures
Let’s take a look at the member variables, mainly the three, Node head, tail, and state
There are also offsets. StateOffset represents the offset of the state field in the memory of the AQS class relative to the first address of the class.
A Java object can be viewed as a section of memory in which each field must be placed in a certain order. This method tells you exactly what byte offset a field has relative to the object’s starting memory address. Used later in compareAndSwapInt to locate the object’s location in memory based on the offset.
Meituan’s AQS principle article is very well written, I will directly take a screenshot here.
1.2.2 Synchronization status State
AQS maintains a field named state, meaning synchronization state, which is modified by Volatile to show how critical resources are currently locked. We can implement exclusive mode and shared mode (locking process) for multiple threads by modifying the synchronization State represented by the State field.
Only one thread can latch, such as ReentrantLock share-share, or multiple threads can latch simultaneously, such as Semaphore/CountDownLatch
1.2.3 Important methods in AQS
Taking the ReentrantLock source code as an example, let’s look at the implementation of the code
public class ReentrantLockDemo {
private ReentrantLock reentrantLock = new ReentrantLock();
public void demo(a) {
reentrantLock.lock();;
try {
// Business logic
} catch (Exception e) {
} finally{ reentrantLock.unlock(); }}}Copy the code
Sync inherits AQS, and the general process is as follows
Conclusion:
AQS defines a synchronizer framework for multi-threaded access to shared resources. Many synchronizers implement different synchronization strategies based on AQS according to different business scenarios, such as ReentrantLock fair lock, non-fair lock, exclusive mode, reentrant, etc., and shared mode Semaphore and CountDownLatch.
reference
StateOffset looks at the principle and application of AQS from the implementation of ReentrantLock