协程(3)

默认顺序

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
import kotlinx.coroutines.*
import kotlin.system.*

fun main() = 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) // pretend we are doing something useful here
return 13
}

suspend fun doSomethingUsefulTwo(): Int {
delay(1000L) // pretend we are doing something useful here, too
return 29
}

在上述代码中,他只拉起了一个协程。在协程内,他也是按顺序一个一个运行的。
因此他最后运行任然会有两秒的延迟。

此外,即使他拉起了两个协程,他也是按照顺序或者时间片分片的方式执行(具体情况我并不清楚)。但是当他delay后,他会将现在的协程先挂起,让其他协程操作。但是同时也只能一个协程执行,也就同步操作。

async实现异步和并发

当通过async来拉起协程时,他将会是一个异步的协程,此时你要通过await()来获取值。

1
2
val one = async { doSomethingUsefulOne() }
val two = async { doSomethingUsefulTwo() }

惰性启动 async

惰性启动即让程序员主动选择何时去拉起这个协程,通过start()和await()方法。
如果不使用start方法,那么他就是一个普通的协程。在async异步协程中,有await()的话,也会等待await()的结果先返回。

结构化并发

因为 async 函数被定义为 CoroutineScope 上的一个扩展函数,所以我们需要将它放在 CoroutineScope 中,这就是 coroutineScope 函数提供的功能:
例如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
suspend fun failedConcurrentSum(): Int = coroutineScope {
val one = async<Int> {
try {
delay(Long.MAX_VALUE) // Emulates very long computation
42
} finally {
println("First child was cancelled")
}
}
val two = async<Int> {
println("Second child throws an exception")
throw ArithmeticException()
}
one.await() + two.await()
}
这样,如果 ```concurrentSum()``` 函数发生错误并引发异常,则在其作用域中启动的所有协程都将被取消