Correctly implementing wait and notify in Kotlin

In general you should use higher-level concurrency utilities when possible.

However, if none of the higher-level constructs work in your case, the direct
replacement is to use a
ReentrantLock and a single
Condition
on that lock.

For example, if your Java code was something like:

private Object lock = new Object();

...

synchronized(lock) {
    ...
    lock.wait();
    ...
    lock.notify();
    ...
    lock.notifyAll();
    ...
}

You can change it to the following Kotlin:

private val lock = ReentrantLock()
private val condition = lock.newCondition()

lock.withLock {           // like synchronized(lock)
    ...
    condition.await()     // like wait()
    ...
    condition.signal()    // like notify()
    ...
    condition.signalAll() // like notifyAll()
    ...
}

While this is slightly more verbose, conditions do provide some extra
flexibility, as you can have multiple conditions on a single lock, and there
are also other kinds of locks (notably ReentrantReadWriteLock.ReadLock and
ReentrantReadWriteLock.WriteLock).

Note that withLock is a Kotlin-provided extension function that takes care of calling Lock.lock()/Lock.unlock() before/after invoking the supplied lambda.

Leave a Comment