Prev Next

Java / Java Concurrency and Multi Threading in Java 17 and Java 21 Interview questions

Explain the internal working of AbstractQueuedSynchronizer (AQS)?

AbstractQueuedSynchronizer is the framework that most of java.util.concurrent's locks and synchronizers, including ReentrantLock, Semaphore, CountDownLatch, and ReentrantReadWriteLock, are built on top of, so understanding it explains how they all share consistent, correct behavior.

flowchart LR
  A[acquire called] --> B{tryAcquire succeeds?}
  B -- Yes --> C[Thread proceeds, holds state]
  B -- No --> D[Thread enqueued in CLH-style wait queue]
  D --> E[Thread parked]
  F[release called] --> G[Head of queue unparked]
  G --> B

At its core, AQS holds a single volatile int state field, and subclasses define what that number means: for ReentrantLock it's the hold count (0 means unlocked, and it increments per reentrant acquisition by the owning thread); for Semaphore it's the number of available permits; for CountDownLatch it's the remaining count.

A thread trying to acquire calls a subclass-defined tryAcquire, which attempts to update state with CAS. If that fails, meaning the resource is unavailable, AQS enqueues the thread as a node in an internal CLH-style (Craig, Landin, and Hagersten) doubly linked wait queue and parks it using LockSupport.park(), which is cheaper than a full OS-level block for a monitor.

When release is called and it updates state to indicate the resource is available again, AQS unparks the thread at the head of the wait queue, which then retries tryAcquire. This shared queue-and-CAS design is why all these different synchronizers behave predictably under contention despite representing very different concepts.

What single field does AQS use to represent a synchronizer's state?
How does AQS handle a thread that fails to acquire the resource?

More Related questions...

What is a thread in Java? What is multithreading in Java? What are the different states of a thread in Java? How do you create a thread in Java? What is the Runnable interface used for? What is a daemon thread in Java? What is thread priority in Java? What is the purpose of the synchronized keyword? What is the purpose of the volatile keyword? What are the types of locks available in java.util.concurrent.locks? Define a race condition in multithreading? What is the Executor framework in Java? What is a virtual thread in Java 21? What is a thread pool? Describe the purpose of the java.util.concurrent package? How does the synchronized keyword achieve mutual exclusion internally? Why should you prefer ReentrantLock over synchronized in some cases? What is the difference between wait() and sleep()? What is the difference between notify() and notifyAll()? How does ConcurrentHashMap achieve thread safety? What is the difference between ConcurrentHashMap and Hashtable? Why should you use CompletableFuture instead of Future? How does the ForkJoinPool execute tasks? What is the difference between Runnable and Callable? How do you handle thread interruption in Java? What happens when a deadlock occurs in a multithreaded application? When should you use CountDownLatch instead of CyclicBarrier? How does compare-and-swap (CAS) work in atomic classes? What is the difference between ExecutorService shutdown() and shutdownNow()? How is the Java Memory Model relevant to concurrent programming? How does ThreadLocal work internally? What is the difference between CopyOnWriteArrayList and a synchronized ArrayList? When would you choose a fixed thread pool over a cached thread pool? How does a BlockingQueue support the producer-consumer pattern? What happens when you call start() twice on the same thread? Explain the lifecycle of a virtual thread in Java 21? Explain the internal working of structured concurrency in Java 21? Why does a synchronized block pin a virtual thread to its carrier thread? What is the difference between ScopedValue and ThreadLocal? Explain the internal working of the ForkJoinPool work-stealing algorithm? How can you optimize code to avoid false sharing? Why does LongAdder outperform AtomicLong under high contention? Why does the ABA problem occur in lock-free CAS-based algorithms? Explain the execution flow of a parallel stream operation? How do you troubleshoot a deadlock in a production Java application? What is the difference between StampedLock and ReadWriteLock? Which is better for high-throughput I/O - platform or virtual threads, and why? How can you optimize a thread pool for mixed CPU-bound and I/O-bound workloads? Explain the internal working of AbstractQueuedSynchronizer (AQS)? Why doesn't increasing the thread pool size always improve throughput?
Show more question and Answers...


Comments & Discussions