我正在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调度程序中受益,而不必创建自己的线程池。

10-05 18:48