CodeBlanks Logo Icon CodeBlanks

Lock and Condition

Learn flexible locks with Lock and Condition.

Lock and Condition

The Lock interface provides more flexible locking than synchronized. ReentrantLock is the most common implementation; lock() acquires, unlock() releases.

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

The finally block always releases the lock. tryLock() returns true if the lock is free; this is useful to avoid deadlocks. Condition also offers await/signal methods.

ReentrantLock features

ReentrantLock lets the same thread acquire the lock multiple times. Each lock() call needs a matching unlock(); this makes nested calls safe.

lock.lock();
lock.lock();  // same thread, OK
// ...
lock.unlock();
lock.unlock();

The fairness parameter favors the longest waiter: new ReentrantLock(true). This reduces starvation. Unlike synchronized, Lock can be tried with a timeout.

Practice Counter with ReentrantLock

Define a LockCounter class with private int count = 0 and private final Lock lock = new ReentrantLock() fields. The public void inc() method calls lock.lock() and does try { count++; } finally { lock.unlock(); }. The public int get() method returns count. In a LockDemo class write main; call inc() three times and print get().

Starter code

Main.java
import java.util.concurrent.locks.*;

// Define the LockCounter class (count, lock, inc, get)

// Write main in LockDemo; call inc three times and print get's result

Sample solution

Main.java
import java.util.concurrent.locks.*;

class LockCounter {
    private int count = 0;
    private final Lock lock = new ReentrantLock();
    public void inc() {
        lock.lock();
        try { count++; } finally { lock.unlock(); }
    }
    public int get() { return count; }
}

class LockDemo {
    public static void main(String[] args) {
        LockCounter c = new LockCounter();
        c.inc();
        c.inc();
        c.inc();
        System.out.println(c.get());
    }
}

Expected output

3

Questions and answers

Review the lesson questions together with their answers. To test yourself, solve the lesson interactively.

1 Complete the Lock release call

Question
Lock lock = new ReentrantLock();
lock.lock();
try {
    count++;
} finally {
    lock.____();
}
Answer
Lock lock = new ReentrantLock();
lock.lock();
try {
    count++;
} finally {
    lock.unlock();
}

Explanation: unlock() releases the lock.

2 Where should unlock() be written when using Lock?

  • In the finally block Correct answer
  • Inside the try block
  • In the catch block
  • Outside main

Explanation: The finally block always releases the lock.

3 Match Lock concepts

Term Meaning
ReentrantLock Most common Lock impl
tryLock Returns true if free
Condition Provides await/signal
fairness Favors longest waiter

All lessons in Advanced