协程搬运工-组合挂起函数

本文涉及的产品
日志服务 SLS,月写入数据量 50GB 1个月
简介: 协程搬运工-组合挂起函数

默认顺序调用


顺序调用两个 suspend 函数的时候,两个函数是串行执行的

  1. 代码
fun main() = runBlocking {
    val startStamp = System.currentTimeMillis()
    a()
    b()
    log("代码运行总时长:${System.currentTimeMillis()-startStamp}")
}
suspend fun a(){
    delay(2000)
    log(A)
}
suspend fun b(){
    delay(3000)
    log(B)
}
复制代码
  1. 日志
日志:  A
日志:  B
日志:  代码运行总时长:5015
复制代码
  1. 结论 协程里面两个并行的 suspend 函数会串行执行,呼应开头的结论


使用 async 实现并发


上面例子中我们使用两个 suspend 函数串行执行函数,如果使用两个 async 执行 suspend 方法的话可以实现并发执行的效果。

aysnc 返回一个 Deferred 对象,Deferred 是一个轻量级阻塞式对象,可以调用 Deferred.await()延迟获取返回结果

Deferred 也是一个 Job,所以也可以取消操作

  1. 代码
fun main() = runBlocking {
    val startStamp = System.currentTimeMillis()
    val deferredA=async {
        a()
    }
    val deferredB=async {
        b()
    }
    deferredA.await()
    deferredB.await()
    log("执行总时长:${System.currentTimeMillis()-startStamp}")
}
suspend fun a(){
    delay(2000)
    log(A)
}
suspend fun b(){
    delay(3000)
    log(B)
}
复制代码
  1. 日志
日志:  A
日志:  B
日志:  执行总时长:3022
复制代码
  1. 结论 上一节中代码执行总耗时 5105,本节总耗时 3022。这说明两个 async 是并发执行的


惰性启动的 async


async 可以通过将 start 参数设置为 CoroutineStart.LAZY 而变为惰性的。 在这个模式下,只有结果通过 await 获取的时候协程才会启动,或者在 Job 的 start 函数调用的时候

  1. 代码
fun main() = runBlocking {
    val deferred = async (start = CoroutineStart.LAZY){
        delay(2000)
        log(A)
        "async执行完成"
    }
    log(deferred.await())
}
复制代码
  1. 日志
日志:  A
日志:  async执行完成
复制代码
  1. 结论
    必须调用 await 或 start 才能启动


使用 async 的结构性并发


协程体作用域中并发的多个 async,有一个发生异常其它的 async 也会被取消

  1. 代码
fun main() = runBlocking {
    async {
        log("吃饭aa,别bb")
        delay(100)
        throw IllegalArgumentException("打你一嘴巴子,你再bb")
    }
   async {
       log("就bb,咋地")
       delay(300)
       log("bb完了")
   }
    log("程序结束")
}
复制代码
  1. 日志
日志:  程序结束
日志:  吃饭aa,别bb
日志:  就bb,咋地
Exception in thread "main" java.lang.IllegalArgumentException: 打你一嘴巴子,你再bb
  at SuspendMethodKt$main$1$1.invokeSuspend(SuspendMethod.kt:55)
复制代码
  1. 记录
    当第一个 async 抛出异常后,第二个 async 后面 “bb 完了”的日志没有打印,说了第二个 async 也同步被取消了。



相关实践学习
日志服务之使用Nginx模式采集日志
本文介绍如何通过日志服务控制台创建Nginx模式的Logtail配置快速采集Nginx日志并进行多维度分析。
相关文章
|
3月前
|
前端开发 安全
协程问题之协程函数返回的Promise对象必须满足哪些要求
协程问题之协程函数返回的Promise对象必须满足哪些要求
|
8天前
|
数据库 开发者 Python
实战指南:用Python协程与异步函数优化高性能Web应用
在快速发展的Web开发领域,高性能与高效响应是衡量应用质量的重要标准。随着Python在Web开发中的广泛应用,如何利用Python的协程(Coroutine)与异步函数(Async Functions)特性来优化Web应用的性能,成为了许多开发者关注的焦点。本文将从实战角度出发,通过具体案例展示如何运用这些技术来提升Web应用的响应速度和吞吐量。
12 1
|
8天前
|
调度 Python
揭秘Python并发编程核心:深入理解协程与异步函数的工作原理
在Python异步编程领域,协程与异步函数成为处理并发任务的关键工具。协程(微线程)比操作系统线程更轻量级,通过`async def`定义并在遇到`await`表达式时暂停执行。异步函数利用`await`实现任务间的切换。事件循环作为异步编程的核心,负责调度任务;`asyncio`库提供了事件循环的管理。Future对象则优雅地处理异步结果。掌握这些概念,可使代码更高效、简洁且易于维护。
11 1
|
3月前
|
前端开发 编译器
协程问题之协程函数参数和局部变量是如何在协程切换时保留的
协程问题之协程函数参数和局部变量是如何在协程切换时保留的
|
3月前
|
数据库 开发者 Python
实战指南:用Python协程与异步函数优化高性能Web应用
【7月更文挑战第15天】Python的协程与异步函数优化Web性能,通过非阻塞I/O提升并发处理能力。使用aiohttp库构建异步服务器,示例代码展示如何处理GET请求。异步处理减少资源消耗,提高响应速度和吞吐量,适用于高并发场景。掌握这项技术对提升Web应用性能至关重要。
75 10
|
3月前
|
数据处理 Python
深入探索:Python中的并发编程新纪元——协程与异步函数解析
【7月更文挑战第15天】Python 3.5+引入的协程和异步函数革新了并发编程。协程,轻量级线程,由程序控制切换,降低开销。异步函数是协程的高级形式,允许等待异步操作。通过`asyncio`库,如示例所示,能并发执行任务,提高I/O密集型任务效率,实现并发而非并行,优化CPU利用率。理解和掌握这些工具对于构建高效网络应用至关重要。
43 6
|
3月前
|
大数据 数据处理 API
性能飞跃:Python协程与异步函数在数据处理中的高效应用
【7月更文挑战第15天】在大数据时代,Python的协程和异步函数解决了同步编程的性能瓶颈问题。同步编程在处理I/O密集型任务时效率低下,而Python的`asyncio`库支持的异步编程利用协程实现并发,通过`async def`和`await`避免了不必要的等待,提升了CPU利用率。例如,从多个API获取数据,异步方式使用`aiohttp`并发请求,显著提高了效率。掌握异步编程对于高效处理大规模数据至关重要。
45 4
|
3月前
|
调度 Python
揭秘Python并发编程核心:深入理解协程与异步函数的工作原理
【7月更文挑战第15天】Python异步编程借助协程和async/await提升并发性能,减少资源消耗。协程(async def)轻量级、用户态,便于控制。事件循环,如`asyncio.get_event_loop()`,调度任务执行。异步函数内的await关键词用于协程间切换。回调和Future对象简化异步结果处理。理解这些概念能写出高效、易维护的异步代码。
45 2
|
3月前
|
Python
从零到一:构建Python异步编程思维,掌握协程与异步函数
【7月更文挑战第15天】Python异步编程提升效率,通过协程与异步函数实现并发。从async def定义异步函数,如`say_hello()`,使用`await`等待异步操作。`asyncio.run()`驱动事件循环。并发执行任务,如`asyncio.gather()`同时处理`fetch_data()`任务,降低总体耗时。入门异步编程,解锁高效代码。
58 1
|
4月前
|
存储 Java 调度
Android面试题之Kotlin 协程的挂起、执行和恢复过程
了解Kotlin协程的挂起、执行和恢复机制。挂起时,状态和上下文(局部变量、调用栈、调度器等)被保存;挂起点通过`Continuation`对象处理,释放线程控制权。当恢复条件满足,调度器重新分配线程,调用`resumeWith`恢复执行。关注公众号“AntDream”获取更多并发知识。
79 2