android - 在 Kotlin Coroutine 的底层,同步是如何发生的?
问题描述
我试图了解协程如何访问其他线程的数据。看看下面的 kotlin 程序,我试图了解variableAccessCount
可以从 Coroutine C1 和 Coroutine C2 访问主线程,但是根据我的理解,协程是在不同线程上运行的一段代码,并且在 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 和改进消息)访问,它们在协程内部运行但在不同的工作线程上.
程序 O/P
Thread[main,5,main]
Thread[DefaultDispatcher-worker-3,5,main]
Thread[DefaultDispatcher-worker-2,5,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++ }
}
推荐阅读
- android - 使函数等待/阻塞然后发出信号以从另一个函数继续的最佳方法
- django - Django通过循环遍历日期范围的每一天进行过滤
- javascript - 构造函数是类的静态方法吗?
- python - 字典列表上的返回值
- templates - 无法使用“添加到愿望清单”和“添加到比较”按钮获取相关产品
- javascript - React - 在减速器中缓存数据?
- kotlin - 未找到 bdd 功能外键
- javascript - 如何让函数从 mousedown 执行到 mouseup 或 mouseleave
- wolfram-mathematica - 在特定情况下测试真相。使用文档编写正确的输入并解释输出
- css - CSS:导航栏下拉菜单固定与粘性意外行为