作者:不能深加工 | 来源:互联网 | 2023-02-01 09:14
根据这个文件,在Kotlin中使用wait
和notify
不鼓励:https://kotlinlang.org/docs/reference/java-interop.html
等待()/通知()
有效的Java Item 69建议更喜欢并发实用程序来wait()和notify().因此,这些方法不适用于Any类型的引用.
但是,该文件没有提出任何正确的方法.
基本上,我想实现一个服务,它将读取输入数据并处理它们.如果没有输入数据,它将暂停,直到有人通知有新的输入数据.就像是
while (true) {
val data = fetchData()
processData(data)
if (data.isEmpty()) {
wait()
}
}
编辑:
我不想使用这些不推荐的方法(反模式),我真的想知道如何正确地做到这一点.
在我的情况下fetchData
从数据库中读取数据,因此在我的情况下不能使用队列.
1> Laurence Gon..:
通常,您应该尽可能使用更高级别的并发实用程序.
但是,如果没有更高级别的构造在您的情况下工作,则直接替换是
在该锁上使用a
ReentrantLock
和single
Condition
.
例如,如果您的Java代码类似于:
private Object lock = new Object();
...
synchronized(lock) {
...
lock.wait();
...
lock.notify();
...
lock.notifyAll();
...
}
您可以将其更改为以下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()
...
}
虽然这稍微冗长一些,但条件确实提供了一些额外的灵活性,因为你可以在一个锁上有多个条件,还有其他类型的锁(特别是ReentrantReadWriteLock.ReadLock
和
ReentrantReadWriteLock.WriteLock
).
注意,这withLock
是一个Kotlin提供的扩展函数,负责调用Lock.lock()
/ Lock.unlock()
调用提供的lambda之前/之后.
2> hotkey..:
BlockingQueue
对于您的用例,A 可以是合适的高级并发实用程序,但应用它需要了解和修改代码结构.
我们的想法是,fetchData()
应该.take()
从队列中的项目,如果队列为空,这将阻止执行,直到出现一个项目,它消除了.wait()
在你的代码.数据的生产者应该.put(t)
将数据放入队列中.
如果你真的需要使用wait
和notify
,例如在低级实现并发实用程序,你可以将Kotlin对象转换为java.lang.Object
并在之后调用这些函数,如语言参考中所述.或者,写为扩展函数:
@Suppress("PLATFORM_CLASS_MAPPED_TO_KOTLIN")
private fun Any.wait() = (this as java.lang.Object).wait()