【发布时间】:2020-08-22 00:27:13
【问题描述】:
我试图了解协程如何访问其他线程的数据。看看下面的 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或LongAdder。 -
它正在执行,请从上面的代码中尝试
-
是的,它有效。但这并不能保证,您将自己暴露在竞争条件下。请参阅Why is i++ not atomic? 的此答案。您所说的“同步”通常称为“原子性”,由我上面提到的类处理。线程也可能有单独的执行,但它们仍然共享内存。
-
了解,但关于您上面的评论,在 Android 中,UI 无法从另一个线程触摸 UI 线程
-
不能,但这是 Android 框架的限制,而不是 JVM(或 Kotlin)。
标签: android multithreading kotlin kotlin-coroutines