示例来自bilibili Kotlin语言深入解析 张龙老师的视频
1 程序运行时间统计measureTimeMillis
fun main() = runBlocking {
// Executes the given block and returns elapsed time in milliseconds.
val elapsedTime = measureTimeMillis {
println("start calculate...")
val value1 = intValue1() // 串行调用挂起方法 时间为挂起函数执行时间累加值
val value2 = intValue2()
println("$value1 + $value2 = ${value1 + value2}")
}
println("total time: $elapsedTime")
}
private suspend fun intValue1(): Int {
delay(2000)
return 15
}
private suspend fun intValue2(): Int {
delay(3000)
return 20
}
class HelloKotlin1 {
}
2 使用async与await实现并发
fun main() = runBlocking {
val elapsedTime = measureTimeMillis {
println("start calculate...")
val deferred1 = async { intValue1() } // 并行调用挂起方法
val deferred2 = async { intValue2() } // 并行调用挂起方法
val value1 = deferred1.await() // 调用await方法来获取最终计算的结果值
val value2 = deferred2.await()
println("$value1 + $value2 = ${value1 + value2}")
}
println("total time: $elapsedTime")
}
private suspend fun intValue1(): Int {
delay(2000)
return 15
}
private suspend fun intValue2(): Int {
delay(3000)
return 20
}
class HelloKotlin2 {
}
3 使用async延时启动协程
注意这里不小心会搞成串行执行协程
fun main() = runBlocking {
val elapsedTime = measureTimeMillis {
val deferred1 = async(start = CoroutineStart.LAZY) { intValue1() } // 并行调用挂起方法
val deferred2 = async(start = CoroutineStart.LAZY) { intValue2() } // 并行调用挂起方法
println("hello...")
Thread.sleep(2000)
// 如果注释调下面两个start调用 协程又会变成串行执行
deferred1.start()
deferred2.start()
println("1...")
val value1 = deferred1.await() // 调用await方法来获取最终计算的结果值 这里需要等待2s(从deferred1.start调用开始计时)
println("2...")
val value2 = deferred2.await() // 调用await方法来获取最终计算的结果值 这里需要等待3s(从deferred2.start调用开始计时)
println("3...")
println("$value1 + $value2 = ${value1 + value2}")
}
println("total time: $elapsedTime")
}
private suspend fun intValue1(): Int {
delay(2000)
return 15
}
private suspend fun intValue2(): Int {
delay(3000)
return 20
}
class HelloKotlin3 {
}
4 异步风格的代码
fun main() {
val elapsedTime = measureTimeMillis {
val deferred1 = intValue1Async() // 调用“普通”方法
val deferred2 = intValue2Async() // 调用“普通”方法
runBlocking {
println("the answer is :${deferred1.await()} + ${deferred2.await()} = ${deferred1.await() + deferred2.await()}")
}
}
println("total time: $elapsedTime")
}
private suspend fun intValue1(): Int {
delay(2000)
return 15
}
private suspend fun intValue2(): Int {
delay(3000)
return 20
}
// GlobalScope.async返回一个Deferred
// 普通方法内部调用异步挂起方法 实际使用该方法看起来就像操作普通方法操作异步方法一样
fun intValue1Async() = GlobalScope.async {
intValue1()
}
// 看起来是普通方法 实际是异步方法
// 1 因为这个方法是普通方法 所以方法调用时可以当做普通方法调用
// 2 如果要获取值 需要使用协程的异步方式执行来获取值
fun intValue2Async() = GlobalScope.async {
intValue2()
}
class HelloKotlin4 {
}
5 正确的异步风格的代码
fun main() = runBlocking {
val elapsedTime = measureTimeMillis {
println("the answer is ${intSum()}")
}
println("total time: $elapsedTime")
}
private suspend fun intValue1(): Int {
delay(2000)
return 15
}
private suspend fun intValue2(): Int {
delay(3000)
return 20
}
private suspend fun intSum(): Int = coroutineScope {// coroutineScope会创建一个新的协程作用域
val deferred1 = async { intValue1() }
val deferred2 = async { intValue2() }
deferred1.await() + deferred2.await()
}
class HelloKotlin5 {
}
6 协程嵌套异常取消问题
fun main() = runBlocking{ try { failureComputation() }finally { println("main end") } } private suspend fun failureComputation(): Int = coroutineScope { val value1 = async { try { delay(90000) 50 } finally { println("value1 end") } } val value2 = async { Thread.sleep(2000) println("value2 throws exception") throw IllegalArgumentException() } value1.await() + value2.await() } class HelloKotlin6 { }



