Encodera

Thanks for reading!

Donate to the site — we work hard for you.

Java reference

ReentrantLock

An explicit lock — a flexible replacement for `synchronized`.

Available since: Java 1.5

Syntax

public class ReentrantLock implements Lock

Examples

A mandatory unlock() in finally:

class Account {
    private final ReentrantLock lock = new ReentrantLock();
    private int balance = 100;
 
    boolean withdraw(int amount) {
        lock.lock();
        try {
            if (balance < amount) return false;
            balance -= amount;
            return true;
        } finally {
            lock.unlock();
        }
    }
 
    int balance() { return balance; }
}
 
void main() throws InterruptedException {
    var acc = new Account();
    var ok = new AtomicInteger();
    Runnable task = () -> { for (int i = 0; i < 10; i++) if (acc.withdraw(10)) ok.incrementAndGet(); };
    Thread a = new Thread(task), b = new Thread(task);
    a.start(); b.start();
    a.join(); b.join();
    IO.println(ok.get() + " withdrawals, balance " + acc.balance());
}

Output:

10 withdrawals, balance 0

Notes

Always call unlock() in finally, otherwise an exception leaves the lock held forever. Unlike synchronized, it can wait with a timeout (tryLock(1, TimeUnit.SECONDS)), be interrupted and work in fair mode. If you do not need these features, synchronized is simpler.

See also

  • synchronized — Lets only one thread at a time run a block of code.
  • AtomicInteger — An integer that can be changed safely from several threads without locks.

In the tutorial

  • Synchronization — Race conditions in Java and how to avoid them — synchronized methods and blocks, atomic classes like AtomicInteger, ReentrantLock and a shared lock object.

Thanks for reading!

Donate to the site — we work hard for you.