我认为使用 launch
从协程上下文调用“挂起”函数会使调用异步。但在下面的示例中,我看到 placeOrder
方法的 2 次调用并未在同一线程中相继运行。
我的错误是什么?
import kotlinx.coroutines.launch
import kotlinx.coroutines.runBlocking
import java.io.File
fun main() = runBlocking {
t("1")
launch {
t("2")
placeOrder("C:\\Users")
t("3")
}
launch {
t("12")
placeOrder("C:\\Program Files")
t("13")
}
t("4")
}
fun t(s: String) {
val currentThread = Thread.currentThread()
println(s + ": " + currentThread.name + " " + currentThread.id)
}
suspend fun placeOrder(d:String): String {
t("placeOrder $d")
val user = createUser(d) // asynchronous call to user service
val order = createOrder(user) // asynchronous call to order service
t("placeOrder $d finished")
return order
}
suspend fun createUser(d:String): String {
t("createUser $d")
val toString = File(d).walk().map {
it.length()
}.sum().toString()
t("createUser $d finished")
return toString
}
suspend fun createOrder(user: String): String {
t("createOrder $user")
val toString = File("C:\\User").walk().map {
it.length()
}.sum().toString()
t("createOrder $user finished")
return toString
}
输出:
1: main 1
4: main 1
2: main 1
placeOrder C:\Users: main 1
createUser C:\Users: main 1
createUser C:\Users finished: main 1
createOrder 1094020270277: main 1
createOrder 1094020270277 finished: main 1
placeOrder C:\Users finished: main 1
3: main 1
12: main 1
placeOrder C:\Program Files: main 1
createUser C:\Program Files: main 1
createUser C:\Program Files finished: main 1
createOrder 5651227104: main 1
createOrder 5651227104 finished: main 1
placeOrder C:\Program Files finished: main 1
13: main 1
最佳答案
您没有编写可挂起的 IO,而是编写了阻塞 IO:
File(d).walk().map {
it.length()
}
您的函数实际上从未挂起,而是阻塞与其 runBlocking
调度程序关联的单个线程。
你没有给你的协程同时执行的机会。
如果您在上述代码周围应用了 withContext(IO) { ... }
,您将获得并发性,但是是普通的旧 Java 类型,几个线程在 IO 操作中一起被阻塞.
关于kotlin - 为什么 Kotlin 协程在同一个线程中顺序运行?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55690292/