如何解决在Kotlin Coroutine的幕后如何进行同步?
我试图了解协程如何访问其他线程的数据。请看下面的kotlin程序,在该程序中我试图了解可以从Coroutine C1和Coroutine C2访问主线程中的variableAccessCount
,但是根据我的理解,协程是在不同线程和Android上运行的一段代码不能直接接触线程,有诸如Handler之类的机制可以实现,在协程中,我们也有 withContext(),但特定于此示例
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import kotlin.coroutines.coroutineContext
var variableAccessCount = 0
fun main() {
println("${Thread.currentThread()}")
GlobalScope.launch {//Coroutine C1
println("${Thread.currentThread()}")
firstAccess() }
GlobalScope.launch {//Coroutine C2
println("${Thread.currentThread()}")
secondAcess() }
Thread.sleep(2000L)
print("The variable is accessed $variableAccessCount number of times")
}
suspend fun firstAccess() {
delay(500L)
variableAccessCount++
}
suspend fun secondAcess() {
delay(1000L)
variableAccessCount++
}
有人可以帮助我了解变量 var functionCalls = 0 在后台如何发生同步。此变量在主线程中声明,可以从两个暂挂函数(completeMessage和ImprovementMessage)中进行访问,在协程内部运行,但是在不同的工作线程上。
程序O / P
Thread[main,5,main]
Thread[DefaultDispatcher-worker-3,main]
Thread[DefaultDispatcher-worker-2,main]
The variable is accessed 2 number of times
解决方法
- 使用
AtomicInteger
:
val variableAccessCount = AtomicInteger(0)
suspend fun firstAccess() {
delay(500L)
variableAccessCount.incrementAndGet()
}
suspend fun secondAcess() {
delay(1000L)
variableAccessCount.incrementAndGet()
}
- 线程限制细粒度
val counterContext = newSingleThreadContext("CounterContext")
var variableAccessCount = 0
suspend fun firstAccess() {
delay(500L)
withContext(counterContext) { variableAccessCount++ }
}
suspend fun secondAcess() {
delay(1000L)
withContext(counterContext) { variableAccessCount++ }
}
- 互斥
val mutex = Mutex()
var variableAccessCount = 0
suspend fun firstAccess() {
delay(500L)
mutex.withLock { variableAccessCount++ }
}
suspend fun secondAcess() {
delay(1000L)
mutex.withLock { variableAccessCount++ }
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。