Lab 11: Advanced Concurrency

Objective

Master advanced java.util.concurrent primitives: Semaphore for resource pooling, ReadWriteLock for read-heavy caches, BlockingQueue producer-consumer, Phaser for multi-phase barrier synchronisation, and CopyOnWriteArrayList for safe concurrent iteration.

Background

ReentrantLock and synchronized serialise all access. Advanced primitives offer more nuance: ReadWriteLock allows many concurrent readers but only one writer — perfect for read-heavy caches. Semaphore limits concurrent access to a fixed number (connection pools). Phaser generalises CyclicBarrier for dynamic party count and multiple phases.

Time

30 minutes

Prerequisites

  • Lab 02 (Virtual Threads), Practitioner Lab 05 (Concurrency)

Tools

  • Docker: zchencow/innozverse-java:latest


Lab Instructions

Steps 1–8: Semaphore pool, ReadWriteLock cache, BlockingQueue producer-consumer, Phaser multi-phase, CopyOnWriteArrayList, StampedLock, Capstone

💡 ReadWriteLock multiplies read throughput. A ReentrantLock allows only one thread at a time — 20 readers must queue up. ReadWriteLock allows all 20 readers to proceed simultaneously, and only pauses them when a writer needs the lock. For a price cache where reads happen 100x more often than writes, this gives ~20x higher throughput.

📸 Verified Output:


Summary

Primitive
Use for

Semaphore(n)

Limit concurrent access to n slots

ReadWriteLock

Multiple readers OR one writer

BlockingQueue

Thread-safe producer-consumer pipeline

Phaser

Multi-phase barrier with dynamic parties

CopyOnWriteArrayList

Safe iteration with infrequent writes

AtomicLong.incrementAndGet()

Lock-free counter

Further Reading

Last updated