Courses/Java/Concurrency Utilities

    Lesson 27 • Advanced

    Concurrency Utilities: Locks, Semaphores & Latches

    Coordinate threads safely with ReentrantLock, Semaphore, and CountDownLatch.

    Before You Start

    You must understand Multithreading (Lesson 26) — thread creation, synchronization, and race conditions. This lesson builds on those concepts with more powerful coordination tools from java.util.concurrent.

    What You'll Learn

    • ✅ ReentrantLock vs synchronized
    • ✅ ReadWriteLock for read-heavy workloads
    • ✅ Semaphore for resource limiting
    • ✅ CountDownLatch for waiting on tasks
    • ✅ CyclicBarrier for phased computation

    1️⃣ Beyond synchronized: Fine-Grained Concurrency

    💡 Analogy: Building Security

    synchronized is like a single master key — it locks the entire building. ReentrantLock is like a keycard system — you can try the door with a timeout, and the same person can re-enter. ReadWriteLock is like a museum — many visitors (readers) simultaneously, but closes for one renovator (writer). Semaphore is like a parking lot — only N cars allowed. CountDownLatch is like a relay race gate — all runners wait until count reaches zero.

    Try It: ReentrantLock & ReadWriteLock

    Try it Yourself »
    JavaScript
    // ReentrantLock & ReadWriteLock
    console.log("=== Locks ===\n");
    
    // 1. ReentrantLock simulation
    console.log("1. REENTRANTLOCK:");
    class ReentrantLock {
        constructor() { this.locked = false; this.owner = null; this.count = 0; }
        lock(thread) {
            if (this.owner === thread) { this.count++; console.log("  [" + thread + "] Re-entered (count: " + this.count + ")"); return true; }
            if (!this.locked) { this.locked = true; this.owner = thread; this.count = 1; console.log("  [" + threa
    ...

    2️⃣ Semaphore & Resource Limiting

    A Semaphore controls access to a limited resource by maintaining a set of permits. acquire() takes a permit (blocks if none available), release() returns one. Common use cases: connection pools, rate limiters, and bounded resource access.

    Try It: Semaphore & CountDownLatch

    Try it Yourself »
    JavaScript
    // Semaphore & CountDownLatch
    console.log("=== Semaphore & Latch ===\n");
    
    // 1. Semaphore — connection pool
    console.log("1. SEMAPHORE (Connection Pool, 3 permits):");
    class Semaphore {
        constructor(permits) { this.permits = permits; this.max = permits; }
        acquire(thread) {
            if (this.permits > 0) { this.permits--; console.log("  [" + thread + "] Acquired ✅ (available: " + this.permits + "/" + this.max + ")"); return true; }
            console.log("  [" + thread + "] Waiting ⏳ (pool ful
    ...

    Try It: Rate Limiter with Semaphore

    Try it Yourself »
    JavaScript
    // Real-World: Rate Limiter
    console.log("=== Rate Limiter with Semaphore ===\n");
    
    class RateLimiter {
        constructor(maxRequestsPerSecond) {
            this.permits = maxRequestsPerSecond;
            this.max = maxRequestsPerSecond;
            this.log = [];
        }
        tryAcquire(requestId) {
            if (this.permits > 0) {
                this.permits--;
                this.log.push({ id: requestId, status: "allowed" });
                return true;
            }
            this.log.push({ id: requestId, status: "reject
    ...

    Common Mistakes

    Forgetting unlock in finally: If an exception occurs, the lock is held forever. Always unlock() in a finally block.
    Deadlock from lock ordering: Thread A locks X then Y; Thread B locks Y then X. Always acquire in consistent global order.
    CountDownLatch when CyclicBarrier needed: CountDownLatch is one-shot. Use CyclicBarrier for repeatable sync points.

    Pro Tips

    💡 tryLock() with timeout prevents deadlocks: if (lock.tryLock(5, TimeUnit.SECONDS)).

    💡 StampedLock (Java 8+) is faster than ReadWriteLock — supports optimistic reads without acquiring a lock.

    💡 Semaphore as rate limiter: Create with N permits and use tryAcquire() to limit API calls.

    📋 Quick Reference

    UtilityAPIUse Case
    ReentrantLocklock() / unlock()Flexible mutual exclusion
    Semaphoreacquire() / release()Limit concurrent access
    CountDownLatchcountDown() / await()Wait for N completions
    CyclicBarrierawait()Sync threads at checkpoint
    ReadWriteLockreadLock() / writeLock()Read-heavy concurrency

    🎉 Lesson Complete!

    You can now coordinate threads with locks, semaphores, and barriers!

    Next: CompletableFuture & async programming.

    Sign up for free to track which lessons you've completed and get learning reminders.

    Previous

    Cookie & Privacy Settings

    We use cookies to improve your experience, analyze traffic, and show personalized ads. You can manage your preferences below.

    By clicking "Accept All", you consent to our use of cookies for analytics and personalized advertising. You can customize your preferences or reject non-essential cookies.

    Privacy PolicyTerms of Service