Appearance
Condition
Using ReentrantLock
is safer than directly using synchronized
and can replace synchronized
for thread synchronization.
However, while synchronized
can be used with wait
and notify
to make threads wait when conditions are not met and wake them up when conditions are satisfied, how can we implement the wait
and notify
functionalities using ReentrantLock
?
The answer is to use the Condition
object to achieve the functionalities of wait
and notify
.
Using the TaskQueue
example, let's implement the functionality previously achieved with synchronized
using ReentrantLock
and Condition
:
java
class TaskQueue {
private final Lock lock = new ReentrantLock();
private final Condition condition = lock.newCondition();
private Queue<String> queue = new LinkedList<>();
public void addTask(String s) {
lock.lock();
try {
queue.add(s);
condition.signalAll();
} finally {
lock.unlock();
}
}
public String getTask() {
lock.lock();
try {
while (queue.isEmpty()) {
condition.await();
}
return queue.remove();
} finally {
lock.unlock();
}
}
}
As seen, when using Condition
, the Condition
object must be obtained from the Lock
instance's newCondition()
method. This ensures that the Condition
instance is bound to the Lock
instance.
The Condition
methods await()
, signal()
, and signalAll()
function similarly to the wait()
, notify()
, and notifyAll()
methods of the synchronized
lock object. Their behaviors are also the same:
await()
releases the current lock and enters a waiting state.signal()
wakes up a single waiting thread.signalAll()
wakes up all waiting threads.- After being awakened, threads must reacquire the lock before continuing execution.
Additionally, similar to tryLock()
, await()
can wait for a specified period. If the thread is not awakened by another thread calling signal()
or signalAll()
within the specified time, it can wake up on its own:
java
if (condition.await(1, TimeUnit.SECONDS)) {
// Woken up by another thread
} else {
// Not awakened within the specified time
}
This demonstrates that by using Condition
in conjunction with Lock
, we can achieve more flexible thread synchronization.
Summary
Condition
can replacewait
andnotify
.Condition
objects must be obtained fromLock
objects.