IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 移动开发 -> Kotlin学习笔记25 协程part5 协程的同步与异步 -> 正文阅读

[移动开发]Kotlin学习笔记25 协程part5 协程的同步与异步

参考链接

示例来自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 {
}

  移动开发 最新文章
Vue3装载axios和element-ui
android adb cmd
【xcode】Xcode常用快捷键与技巧
Android开发中的线程池使用
Java 和 Android 的 Base64
Android 测试文字编码格式
微信小程序支付
安卓权限记录
知乎之自动养号
【Android Jetpack】DataStore
上一篇文章      下一篇文章      查看所有文章
加:2021-10-16 19:45:19  更:2021-10-16 19:46:08 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/23 23:35:18-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码