Backend Development 16 min read

Understanding Java J.U.C Locks: ReentrantLock, ReentrantReadWriteLock, and Condition

This article introduces Java's java.util.concurrent (J.U.C) package, explains its lock mechanisms—including Lock, ReentrantLock, ReentrantReadWriteLock, and Condition—provides detailed code examples, and discusses lock types such as fair, non‑fair, and read/write locks for effective multithreaded synchronization.

Rare Earth Juejin Tech Community
Rare Earth Juejin Tech Community
Rare Earth Juejin Tech Community
Understanding Java J.U.C Locks: ReentrantLock, ReentrantReadWriteLock, and Condition

Java's concurrency utilities are provided by the java.util.concurrent (J.U.C) package. Before JDK 1.5 only synchronized and volatile were available; J.U.C adds a rich set of tools such as locks, atomic classes, concurrent collections, thread pools, and other utilities.

J.U.C originated from Doug Lea's independent concurrent library and was incorporated into JDK 1.5 via JSR‑166. Its main functional areas are:

Locks (e.g., ReentrantLock , ReentrantReadWriteLock )

Atomic classes (e.g., AtomicInteger )

Concurrent containers (e.g., ConcurrentHashMap )

Non‑blocking queues (e.g., ConcurrentLinkedQueue )

Executor framework (thread pools)

Synchronization utilities (e.g., CountDownLatch , CyclicBarrier , Semaphore )

The core lock abstraction is the Lock interface:

package java.util.concurrent.locks;

import java.util.concurrent.TimeUnit;

public interface Lock {
    void lock();
    void lockInterruptibly() throws InterruptedException;
    boolean tryLock();
    boolean tryLock(long time, TimeUnit unit) throws InterruptedException;
    void unlock();
    Condition newCondition();
}

Its methods provide explicit lock acquisition, interruptible acquisition, timed attempts, release, and the ability to create a Condition object for thread communication.

The Condition interface mirrors Object.wait/notify but works with explicit locks:

package java.util.concurrent.locks;

import java.util.Date;
import java.util.concurrent.TimeUnit;

public interface Condition {
    void await() throws InterruptedException;
    void awaitUninterruptibly();
    long awaitNanos(long nanosTimeout) throws InterruptedException;
    boolean await(long time, TimeUnit unit) throws InterruptedException;
    boolean awaitUntil(Date deadline) throws InterruptedException;
    void signal();
    void signalAll();
}

ReentrantLock is a re‑entrant mutual‑exclusion lock that can be created as fair or non‑fair:

ReentrantLock lock = new ReentrantLock(); // non‑fair
ReentrantLock fairLock = new ReentrantLock(true); // fair

Typical usage follows the pattern:

Lock lock = new ReentrantLock();
try {
    lock.lock();
    // critical section
} finally {
    lock.unlock();
}

The lock supports additional queries such as getHoldCount() , isHeldByCurrentThread() , getQueueLength() , isFair() , and isLocked() . A demo class ReentrantLockDemo shows multiple threads acquiring the lock, nesting lock calls, and inspecting these properties.

tryLock offers non‑blocking acquisition:

if (lock.tryLock(1, TimeUnit.SECONDS)) {
    try {
        // work
    } finally {
        lock.unlock();
    }
} else {
    System.out.println(Thread.currentThread().getName() + " failed to get lock");
}

When a lock is held, a Condition can be used for thread communication. The following example creates a lock, obtains a condition, and demonstrates await() and signalAll() :

// source: https://github.com/kevinyan815/JavaXPlay/... 
package com.learnconcurrent.lockwaitnotify;

import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class LearnLockWaitNotifyAppMain {
    public static void main(String[] args) {
        Lock locker = new ReentrantLock();
        Condition condition = locker.newCondition();
        int workingSec = 2;
        int threadCount = 3;
        for (int i = 0; i < threadCount; i++) {
            new Thread(() -> {
                System.out.println(getName() + ": thread starts");
                try {
                    locker.lock();
                    sleepSec(workingSec);
                    System.out.println(getName() + ": awaiting");
                    condition.await();
                    System.out.println(getName() + ": resumed");
                    sleepSec(workingSec);
                    System.out.println(getName() + ": finished");
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } finally {
                    locker.unlock();
                }
            }, "Worker" + i).start();
        }
        System.out.println("--- main thread sleeping ---");
        sleepSec(workingSec + 1);
        System.out.println("--- waking all workers ---");
        try {
            locker.lock();
            condition.signalAll();
        } finally {
            locker.unlock();
        }
    }
    private static void sleepSec(int sec) {
        try { Thread.sleep(TimeUnit.SECONDS.toMillis(sec)); } catch (InterruptedException e) { e.printStackTrace(); }
    }
    private static String getName() { return Thread.currentThread().getName(); }
}

ReentrantReadWriteLock provides separate read and write locks for scenarios with many reads and few writes. The ReadWriteLock interface defines readLock() and writeLock() :

package java.util.concurrent.locks;

public interface ReadWriteLock {
    Lock readLock();
    Lock writeLock();
}

The concrete class ReentrantReadWriteLock implements this interface, offering re‑entrant read and write locks. Unlike ReentrantLock , the read lock does not support a Condition for waiting.

In summary, the article covered the various lock types provided by Java's J.U.C package—basic Lock , re‑entrant mutual‑exclusion locks, fair vs. non‑fair policies, read/write locks, and condition variables—preparing the reader for the next topic on atomic operations.

JavaConcurrencyLocksJUCReentrantLockCondition
Rare Earth Juejin Tech Community
Written by

Rare Earth Juejin Tech Community

Juejin, a tech community that helps developers grow.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.