一、默认顺序调用
假设我们在不同的地方定义了两个进行某种调用远程服务或者进行计算的挂起函数。我们只
假设它们都是有用的,但是实际上它们在这个示例中只是为了该目的而延迟了一秒钟:
suspend fun doSomethingUsefulOne(): Int {
delay(1000L) // 假设我们在这里做了一些有用的事
return 13
}
suspend fun doSomethingUsefulTwo(): Int {
delay(1000L) // 假设我们在这里也做了一些有用的事
return 29
}
如果需要按 顺序 调用它们,我们接下来会做什么——首先调用 doSomethingUsefulOne 接下来
调用 doSomethingUsefulTwo ,并且计算它们结果的和吗? 实际上,如果我们要根据第一个函
数的结果来决定是否我们需要调用第二个函数或者决定如何调用它时,我们就会这样做。
我们使用普通的顺序来进行调用,因为这些代码是运行在协程中的,只要像常规的代码一样
顺序 都是默认的。下面的示例展示了测量执行两个挂起函数所需要的总时间:
runBlocking<Unit> {
//sampleStart
val time = measureTimeMillis {
val one = doSomethingUsefulOne()
val two = doSomethingUsefulTwo()
println("The answer is ${one + two}")
}
println("Completed in $time ms")
//sampleEnd
}
suspend fun doSomethingUsefulOne(): Int {
delay(1000L) // 假设我们在这里做了些有用的事
return 13
}
suspend fun doSomethingUsefulTwo(): Int {
delay(1000L) // 假设我们在这里也做了一些有用的事
return 29
}
它的打印输出如下:
The answer is 42
Completed in 2017 ms
二、使用async并发
如果 doSomethingUsefulOne 与 doSomethingUsefulTwo 之间没有依赖,并且我们想更快的得到
结果,让它们进行 并发 吗?这就是 async 可以帮助我们的地方。
在概念上,async 就类似于 launch。它启动了一个单独的协程,这是一个轻量级的线程并与其
它所有的协程一起并发的工作。不同之处在于 launch 返回一个 Job 并且不附带任何结果
值,而 async 返回一个 Deferred —— 一个轻量级的非阻塞 future, 这代表了一个将会在稍后
提供结果的 promise。你可以使用 .await() 在一个延期的值上得到它的最终结果, 但是
Deferred 也是一个 Job ,所以如果需要的话,你可以取消它。
runBlocking {
//sampleStart
val time = measureTimeMillis {
val one = async { doSomethingUsefulOne() }
val two = async { doSomethingUsefulTwo() }
println("The answer is ${one.await() + two.await()}")
}
println("Completed in $time ms")
//sampleEnd
suspend fun doSomethingUsefulOne(): Int {
delay(1000L) // 假设我们在这里做了些有用的事
return 13
}
suspend fun doSomethingUsefulTwo(): Int {
delay(1000L) // 假设我们在这里也做了一些有用的事
return 29
}
它的打印输出如下:
The answer is 42
Completed in 1017 ms
这里快了两倍,因为两个协程并发执行。 请注意,使用协程进行并发总是显式的。
推荐文章
1267

被折叠的 条评论
为什么被折叠?



