我在Kotlin中有以下代码
import kotlinx.coroutines.experimental.async
import kotlinx.coroutines.experimental.delay
import kotlinx.coroutines.experimental.runBlocking
fun main(args: Array<String>) {
runBlocking {
val async1 = async {
println("1st")
delay(2000)
println("1st end")
}
val async2 = async {
println("2nd")
delay(1000)
println("2nd end")
}
async1.await()
async2.await()
println("end")
}
}
输出为
1st
2nd
2nd end
1st end
end
我的理解是await()
是一个暂停函数,这意味着执行被“暂停”在那里。因此,我认为实际上首先执行async1
,然后执行async2
。所以我希望输出是
1st
1st end
2nd
2nd end
end
显然发生的是,async1
和async2
都并行执行,可以看作async1
的输出夹在async2
的输出之间
所以我现在的具体问题是:为什么Kotlin没有在async1
上暂停,而是同时启动async2
?
答案 0 :(得分:1)
await()
将挂起它在其中运行的协程-这是您的主要块(并且线程runBlocking()
正在运行,因为它正在阻塞),因此不会调用async2.await()
,除非{ {1}}完成。
但是由于async1
函数的执行是立即开始的,并且默认情况下将在后台线程池中执行,因此不会被阻塞。
您可以通过添加
async()
然后看到,“ between”将始终在“ 1st end”之后打印
如果您希望协程顺序运行,请使用 async1.await()
println("between")
async2.await()
构建器(或者在大多数情况下,在这种情况下根本不需要使用协程)
异步/等待的想法是并行运行任务,并且在等待其中一个任务的结果时不要阻塞其他任务。
答案 1 :(得分:0)
为什么Kotlin没有在
async1
上暂停,而是同时启动async2
?
async
在后台生成一个新任务。任务立即开始执行。您无法控制其暂停,并且在整个用例中,它永远不会被暂停。我们经常使用async
将阻止任务提交到线程池。
await
暂停当前协程,直到任务完成并产生结果。它对任务的执行没有影响。即使您从不致电await
,任务也将完成。
如果您特别想仅在调用await
时触发任务,则可以指定start = LAZY
:
runBlocking {
val async1 = async(start = LAZY) {
println("1st")
delay(2000)
println("1st end")
}
val async2 = async(start = LAZY) {
println("2nd")
delay(1000)
println("2nd end")
}
async1.await()
async2.await()
println("end")
}
这将按照您期望的顺序可靠地打印。