tof*_*for 5 coroutine kotlin kotlin-coroutines
能否请您解释一下这两段代码之间的区别.第一次打印421,但第二次打印606.为什么第一个是平行的而第二个是顺序的?
fun main(args: Array<String>) = runBlocking {
var time = measureTimeMillis {
val one = async { one() }
val two = async { two() }
val int1 = one.await()
val int2 = two.await()
println(int1 + int2)
}
println(time)
time = measureTimeMillis {
val one = async { one() }.await()
val two = async { two() }.await()
println(one + two)
}
print(time)
}
suspend fun one(): Int {
delay(200)
return 12
}
suspend fun two(): Int {
delay(400)
return 23
}
Run Code Online (Sandbox Code Playgroud)
Mar*_*nik 15
val one = async { one() }
val two = async { two() }
val int1 = one.await()
val int2 = two.await()
Run Code Online (Sandbox Code Playgroud)
这是做什么的:
val one = async { one() }.await()
val two = async { two() }.await()
Run Code Online (Sandbox Code Playgroud)
这是做什么的:
这里没有并发性,它是纯粹的顺序代码.实际上,对于顺序执行,您甚至不应该使用async.正确的习语是
val one = withContext(Dispatchers.Default) { one() }
val two = withContext(Dispatchers.Default) { two() }
Run Code Online (Sandbox Code Playgroud)
在第一个变体中,您会得到Deferred<Int>两个异步调用的 a 。正如的文档Deferred很好地显示的那样,延迟对象可能处于几种状态。从外部来看,该状态现在要么是new要么,active但肯定还没有完成。然而,在您的第二个变体中,第一个异步等待completed已经需要一个状态,否则您在那里无法获得任何值。然而,你的async{one()}.await()第二个async还不知道。另请注意, 的返回值await()是现在Int,不再Deferred是,因此此时协程一定已经执行。另请检查的文档await()。
换句话说:
val one = async { one() }
val two = async { two() }
Run Code Online (Sandbox Code Playgroud)
现在one都是和。尚未调用任何内容(或可能已调用)。一旦您调用它,它可能就已经启动了和,只是因为它拥有它的资源(即使您没有在代码中的任何地方使用)。twoDeferred<Int>one.await()onetwotwo.await()
然而,对于第二种变体:
val one = async { one() }.await()
val two = async { two() }.await()
Run Code Online (Sandbox Code Playgroud)
即使它创建了一个协程,async {one()}它也必须立即设置一个值one,因为您正在调用await()它。one和的类型two都是Int. 因此,一旦命中第一行,就需要立即执行异步代码。到那时,没有人知道在我们等待第一个异步调用的值时必须执行另一个异步调用。如果第一个没有await,协程将再次并行执行,例如:
val one = async { one() }
val two = async { two() }.await()
Run Code Online (Sandbox Code Playgroud)
将并行one()执行。two()
因此,也许这可以总结为:只有那些协程可以在等待时并行执行,那时它们是已知的/生成的。
| 归档时间: |
|
| 查看次数: |
5763 次 |
| 最近记录: |