gpt4 book ai didi

kotlin - 在 Kotlin 中锁定互斥锁的正确方法

转载 作者:行者123 更新时间:2023-12-05 02:42:43 24 4
gpt4 key购买 nike

我想使用 Kotlin Coroutines 实现一个简单的线程安全 Buffer,因为项目中已经使用了协程。

缓冲区将在多线程和单线程上下文中使用,因此使用 suspend fun getMostRecentData() 似乎不太合理(请参见下面的代码)。

这就是我目前所拥有的。事实上,我必须编写所有代码来锁定互斥锁,这让我想知道我是否做错了什么。

无论如何,这是代码:

class SafeBuffer(
private val dispatcher: CoroutineDispatcher,
private val bufferSize: Int
) {

private val buffer = LinkedList<MyDataType>()
private val mutex = Mutex()

val size: Int
get() = buffer.size

// First approach: make a suspend fun
// Not great because I will need a runBlocking{} statement somewhere, every time I want to access the buffer
suspend fun getMostRecentData() : MyDataType? {
mutex.withLock {
return if (buffer.isEmpty()) null else buffer.last
}
}

// Second approach: use a runBlocking block inside the function
// Seems like it is missing the purpose of coroutines, and I'm not
// sure it is actually thread safe if other context is used somehow?
fun getMostRecentData() : MyDataType? {
runBlocking(dispatcher) {
mutex.withLock {
return if (buffer.isEmpty()) null else buffer.last
}
}
}

/**** More code ****/
(...)

}

那么实现这一目标的最惯用/最优雅的方式是什么?

最佳答案

扩展我的评论,我认为让缓冲区类只公开一个suspend fun 是惯用的,因为类的使用者将负责弄清楚他们想如何使用它(通过 runBlocking 或来自另一个协程)。如果您发现此用例经常出现,惯用的方法可能是在 SafeBuffer 上添加一个扩展函数来提供此功能。

扩展函数在协程 API 中随处可见。在您的代码示例中,甚至 Mutex.withLock 也被定义为扩展函数。

class SafeBuffer(...) {

private val buffer = LinkedList<MyDataType>()
private val mutex = Mutex()

suspend fun getMostRecentData() : MyDataType? =
mutex.withLock {
if (buffer.isEmpty()) null else buffer.last
}
}

fun SafeBuffer.getMostRecentDataBlocking(): MyDataType? =
runBlocking {
getMostRecentData()
}

关于kotlin - 在 Kotlin 中锁定互斥锁的正确方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67321436/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com