参考链接
示例来自bilibili Kotlin语言深入解析 张龙老师的视频
1 程序运行时间统计measureTimeMillis
/**
* 程序运行时间统计measureTimeMillis
*
* Kotlin 提供了一个便利的内置函数来统计运行时间(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实现并发
/**
* 使用async与await实现并发
* 从概念上讲,async就像是launch一样。它会开启一个单独的协程,这个协程也是轻量级线程,可以与其他协程并发工作。区别在于,launch
* 会返回一个Job 但是Job不会持有任何结果值,而async会返回一个Deferred,Deferred是一个轻量级非阻塞的future,代表一个promise
* 可以在之后提供一个结果值
*
* 可以通过在一个deferred上调用await方法来获取最终计算的结果值,Deferred是Job的子类,因此可以在需要时取消Job
*/
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延时启动协程
注意这里不小心会搞成串行执行协程
/**
* 使用async延时启动协程
*
* 我们可以通过将async方法的start方法参数设置为 CoroutineStart.LAZY来实现协程的延迟执行
* 在这种情况下,协程会在如下情况执行:
* 1.调用deferred的await方法
* 2.调用job的start方法
*/
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 异步风格的代码
/**
* 异步风格的代码
*
* 不推荐??原因不理解 TODO
*/
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 正确的异步风格的代码
/**
* 正确的异步风格的代码
*
* 推荐使用一个挂起函数调用需要并行执行的另外的挂起方法
* 但是还是不明白HelloKotlin4中的代码有什么缺陷
* 使用async进行结构化并发程序开发
*/
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<Unit> {
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<Int> {
Thread.sleep(2000)
println("value2 throws exception")
throw IllegalArgumentException()
}
value1.await() + value2.await()
}
class HelloKotlin6 {
}
|