我正在Kotlin协程中迈出第一步,但我遇到了问题。
为了创建Foo
并从函数返回它,我需要异步调用两个繁重的服务方法来获取Foo
创建的一些值。这是我的代码:
return runBlocking {
val xAsync = async {
service.calculateX()
}
val yAsync = async {
service.calculateY()
}
Foo(xAsync.await(), yAsync.await())
};
但是,在我看来,阅读日志后,
calculateX()
和calculateY()
会被同步调用。我的代码正确吗? 最佳答案
您的代码并不完美,但是就使calculateX()
和calculateY()
同时运行而言,它是正确的。但是,由于它是在单线程的runBlocking
调度程序上启动此并发工作的,并且由于您的重量级操作正在阻塞而不是挂起,因此它们不会并行化。
第一个观察到的结果是,与Java执行程序的老式方法相比,阻塞操作无法从协程中获得任何好处,除了API更加简单之外。
第二个观察结果是,您至少可以使用IO调度程序使它们并行运行,每个线程都阻塞自己的线程:
return runBlocking {
val xAsync = async(Dispatchers.IO) {
service.calculateX()
}
val yAsync = async(Dispatchers.IO) {
service.calculateY()
}
Foo(xAsync.await(), yAsync.await())
};
与使用
java.util.concurrent
API相比,在这里您可以从库的IO调度程序中受益,而不必创建自己的线程池。