MVP*_*MVP 7 concurrency synchronized kotlin
想知道是否有人可以提供帮助,我正在尝试了解使用两个线程访问 Kotlin 中的集合的正确方法。
下面的代码模拟了我在实时系统中遇到的问题。一个线程迭代集合,但另一个线程可以删除该数组中的元素。
我尝试将 @synchronized 添加到集合 getter 中,但这仍然给了我一个并发修改异常。
谁能告诉我这样做的正确方法是什么?
class ListTest() {
val myList = mutableListOf<String>()
@Synchronized
get() = field
init {
repeat(10000) {
myList.add("stuff: $it")
}
}
}
fun main() = runBlocking<Unit> {
val listTest = ListTest()
launch(Dispatchers.Default) {
delay(1L)
listTest.myList.remove("stuff: 54")
}
launch {
listTest.myList.forEach { println(it) }
}
}
Run Code Online (Sandbox Code Playgroud)
Ten*_*r04 11
您只是同步 getter 和 setter,因此当您开始使用列表中的引用时,它已经被解锁。
Kotlin 具有 Mutex 类,可用于共享可变对象的锁定操作。Mutex 比 Java 更好synchronized,因为它挂起而不是阻塞协程线程。
您的示例在现实世界中可能是糟糕的设计,因为您的类公开公开了一个可变列表。但同时也要确保修改列表至少是安全的:
class ListTest() {
private val myListMutex = Mutex()
private val myList = mutableListOf<String>()
init {
repeat(10000) {
myList.add("stuff: $it")
}
}
suspend fun modifyMyList(block: MutableList<String>.() -> Unit) {
myListMutex.withLock { myList.block() }
}
}
fun main() = runBlocking<Unit> {
val listTest = ListTest()
launch(Dispatchers.Default) {
delay(1L)
listTest.modifyMyList { it.remove("stuff: 54") }
}
launch {
listTest.modifyMyList { it.forEach { println(it) } }
}
}
Run Code Online (Sandbox Code Playgroud)
如果您不使用协程,则Mutex()可以使用Anyand 来代替withLock使用,synchronized (myListLock) {}就像在 Java 中一样,以防止同步块中的代码同时运行。
| 归档时间: |
|
| 查看次数: |
9598 次 |
| 最近记录: |