According to this document, using wait
and notify
is discouraged in Kotlin: https://kotlinlang.org/docs/reference/java-interop.html
wait()/notify()
Effective Java Item 69 kindly suggests to prefer concurrency utilities to wait() and notify(). Thus, these methods are not available on references of type Any.
However the document does not propose any correct way of doing it.
Basically, I would like to implement a service, which would read the input data and process them. If there were no input data, it would suspend itself until someone notifies that there are new input data. Something like
while (true) { val data = fetchData() processData(data) if (data.isEmpty()) { wait() } }
EDIT:
I don't want to use these not recommended methods (antipatterns), I really want to find out how to do this properly.
In my case fetchData
reads data from the database, so queues in my case cannot be used.
The wait() Method Simply put, calling wait() forces the current thread to wait until some other thread invokes notify() or notifyAll() on the same object. For this, the current thread must own the object's monitor.
The wait() method causes the current thread to wait until another thread invokes the notify() or notifyAll() methods for that object. The notify() method wakes up a single thread that is waiting on that object's monitor. The notifyAll() method wakes up all threads that are waiting on that object's monitor.
wait method tells the current thread (thread which is executing code inside a synchronized method or block) to give up monitor and go to waiting state. notify method wakes up a single thread that is waiting on this object's monitor. notifyAll method wakes up all the threads that called wait() on the same object.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With