Kotlin coruntines在启动和回调时不会执行
我以为我对Kotlin的协同程序已经足够熟悉了,直到我得到了这个代码 1到8都是打印的,除了2:Kotlin coruntines在启动和回调时不会执行,kotlin,kotlin-coroutines,Kotlin,Kotlin Coroutines,我以为我对Kotlin的协同程序已经足够熟悉了,直到我得到了这个代码 1到8都是打印的,除了2: import kotlinx.coroutines.* import java.lang.Runnable import java.lang.Thread.sleep import kotlin.concurrent.thread fun main() { runBlocking { Client.createAccount() delay(1000)
import kotlinx.coroutines.*
import java.lang.Runnable
import java.lang.Thread.sleep
import kotlin.concurrent.thread
fun main() {
runBlocking {
Client.createAccount()
delay(1000)
}
}
object Client: CoroutineScope {
override val coroutineContext = newSingleThreadContext("Client")
fun createAccount() = launch {
Client2.init(Runnable {
println('1')
launch {
println('2')
}
ok()
ok2()
})
println('7')
launch {
println('8')
}
}
fun ok() {
println('3')
launch {
println('4')
}
}
fun ok2() = launch {
println('5')
launch {
println('6')
}
}
}
object Client2 {
fun init(runnable: Runnable) = thread {
sleep(100)
runnable.run()
}
}
结果是:
7
8
1
3
4
5
6
回调中的协程将永远不会被调用。为什么?
如果我删除createAccount()
中的launch
,1到8都将被打印出来。
另外,如果我使用
GlobalScope.launch{println('2')}
而不是launch{println('2')}
,我还可以打印2。launch在处理程序中发布一个Runnable,因此它的代码不会立即执行。
launch(Dispatchers.Main、CoroutineStart.UNDISPATCHED)将立即在当前线程中执行其lambda表达式
将调度程序更改为当前正在使用的调度程序
将午餐从线内改为
launch (coroutineContext, CoroutineStart.UNDISPATCHED)
输出:
7
8
1
2
3
4
5
6
原因是匿名类将其包装作用域用作父类 当父作业
createAccount()
启动完成时,Runnable{}
中的launch{println('2')}
将被取消
因此,无法调用它,因为它将在启动{println('8')}
后立即取消
因此,如果您像下面这样更改客户端
,它将正确打印“2”
object Client: CoroutineScope {
override val coroutineContext = Dispatchers.Main
fun createAccount() = launch {
Client2.init(Run())
println("7")
launch {
println("8")
}
}
fun ok() {
println("3")
launch {
println("4")
}
}
fun ok2() = launch {
println("5")
launch {
println("6")
}
}
class Run: Runnable {
override fun run() {
println("1")
launch {
println("2")
}
ok()
ok2()
}
}
}
你真的解决了我的问题!您能给我一些指南或文档来了解包装器作用域的行为吗?非常感谢。我不确定。。。但匿名内部类最初在jvm中具有包装依赖性,而不是通过协同路由。如果我错了,请让我知道。(+我通过转换成kotlin字节码解决了你的问题)谢谢你给我这个解决方案,它工作得很好!我还找到了CoroutineStart.ATOMIC,但我不明白为什么会打印4和6,而不会打印2。Choim回答我的疑问,也许你可以看看
object Client: CoroutineScope {
override val coroutineContext = Dispatchers.Main
fun createAccount() = launch {
Client2.init(Run())
println("7")
launch {
println("8")
}
}
fun ok() {
println("3")
launch {
println("4")
}
}
fun ok2() = launch {
println("5")
launch {
println("6")
}
}
class Run: Runnable {
override fun run() {
println("1")
launch {
println("2")
}
ok()
ok2()
}
}
}