编写挂起函数
默认顺序
当需要按顺序调用挂起函数时,可以直接顺序书写来调用它们
fun main() = runBlocking {
val time = measureTimeMillis {
doSomethingUsefulOne()
doSomethingUsefulTwo()
}
println(time)
}使用 async 并发
可以使用async函数使得任务并发执行,它在概念上与launch类似,但不同之处在于launch返回一个Job并且不携带任何结果,而async返回了一个Deferred,一个轻量级非阻塞的future,可以使用await来获取它的执行结果,但Deferred也是一个Job,可以和Job一样被控制
runBlocking {
val time = measureTimeMillis {
val one = async { doSomethingUsefulTwo() }
val two = async { doSomethingUsefulTwo() }
"result is ${one.await() + two.await()}"
}
}惰性启动 async
可以设置协程的start参数为LAZY,从而使得async变为惰性
只有当获取async值或者调用start方法时,async的结果才会被计算
但如果直接调用await输出值,将会导致async顺序执行,因为await将启动协程并等待其完成
val time = measureTimeMillis {
val one = async(start = CoroutineStart.LAZY) { doSomethingUsefulOne() }
val two = async(start = CoroutineStart.LAZY) { doSomethingUsefulTwo() }
one.start()
two.start()
println("result = ${one.await() + two.await()}")
}异步风格的函数
这种风格是其它语言中的风格,不建议在Kotlin中这样使用
可以使用异步协程构建器定义异步调用的异步风格函数,并使用GlobalScope来取消结构化并发,使用..Async后缀来定义这种函数,以强调它们仅仅是用于启动异步计算
@OptIn(DelicateCoroutinesApi::class)
fun somethingUsefulTwoAsync() = GlobalScope.async {
doSomethingUsefulOne()
}
@OptIn(DelicateCoroutinesApi::class)
fun somethingUsefulOneAsync() = GlobalScope.async {
doSomethingUsefulTwo()
}GlobalScope是一个精密的 API,在调用它时,很容易导致意外创建资源或者内存泄漏的问题,要使用它需要加上@OptIn(DelicateCoroutinesApi::class)注解
Last updated on