Lock and Condition
- Java course
- Advanced
- Lesson 65/82
- 5 min
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
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 resultSample solution
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
Lock lock = new ReentrantLock();
lock.lock();
try {
count++;
} finally {
lock.____();
}
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 |