首页 > 解决方案 > 在 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

标签: androidmultithreadingkotlinkotlin-coroutines

解决方案


  • 使用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++ }
}

推荐阅读