• Kotlin - 挂起函数 suspend


    挂起函数的作用

    切线程去做别的事,做完后携带结果返回来,从之前的进度继续往下做事。

    挂起恢复的过程

    ①挂起函数挂起的是它所在的协程(直接包裹该挂起函数的那个协程,协程存在嵌套),。

    • 此时被挂起的协程:代码不会继续往下执行(即写在挂起函数下面的那些,而挂起函数上面的代码没执行完的话,挂起函数指定在相同线程执行会等挂起函数执行完再执行,指定在其它线程则继续并发执行)。
    • 此时被挂起的协程所在的线程:不会阻塞而是继续去执行其他任务或无事可干(就是它原本受系统调度的样子,回收或再利用)。

    ②协程被挂起会返回一个 Continuation(类似游戏中的进度存档点)传递给挂起函数(因此挂起函数只能在协程或其他挂起函数中调用),然后挂起函数在它指定的线程中执行自己的协程(任务代码)。

    ③挂起函数执行完后,通过 Continuation.resume() 传递自己的结果并返回到它所在的协程中,从之前的进度继续往下执行。

    非阻塞式

    本质就是不卡线程(单线程是阻塞式的,当前任务没做完就不会执行后面的代码,切到别的线程处理就不会卡之前的线程)。对比其它基于Java的多线程解决方案,协程的优点是借助Kotlin的语言优势以及挂起恢复功能,让我们方便在同一代码块(作用域)里按照逻辑顺序书写任务代码却执行在不同线程(让看起来同步的方式写出异步代码),即原先串行写的代码现在并行来写(Java切线程会回调里嵌套回调关系复杂,而每个协程执行在自己指定的线程中(创建时通过Dispatchers调度,而不是Thread因为不是单纯指定线程),消除回调看起来像同步那样按上下顺序执行,逻辑直观并消除模板代码),消除多线程异步之间协作任务的操作难度(别人调用起来也不用考虑任务是执行在哪个线程)。

    自定义挂起函数

    由于消除了回调嵌套可以自定义挂起函数:

    • 什么时候定义:需要做耗时操作的时候(I/O、计算、等待)才会挂起当前的协程。
    • 解决了什么:创建者告知这是一个耗时操作,并指定了该协程在后台线程执行,保障了调用者的线程安全。
    • suspend 关键字:用来限制该函数只能在协程里调用或者在其他挂起函数里调用,因为“挂起->执行完->切回去”只有在协程中使用才能实现。真正挂起操作靠的是最终调用的那个协程自带的挂起函数。也有提醒“这是一个耗时操作,是挂起函数要在协程中使用”的意思。

    挂起函数 Suspend Function

    所有官方框架中的挂起函数都是可以取消的。

    suspend挂起当前协程,并保存它的状态(变量)。只能有协程或其他挂起函数调用。
    resume返回到上一个挂起的协程,并从之前的状态中恢复执行。

    delay()

    会延迟协程执行的时间,不会当前阻塞线程,结束后继续执行协程。
    withContext
    suspendCoroutine()

    suspendCoroutine() 

    1. suspend fun main() {
    2. println("AAA")
    3. suspendCoroutine<Unit> { continuation ->
    4. continuation.resume(Unit)
    5. }
    6. println("BBB")
    7. }

  • 相关阅读:
    【Python入门】Numpy基础
    MySQL最大建议行数2000w, 靠谱吗?
    ebay获取商品详情 API接口
    力扣 452. 用最少数量的箭引爆气球
    goroutine 调度器
    虚函数(多态)
    [论文-ing]Weakly Supervised Universal Fracture Detectionin Pelvic X-rays
    本人在学习Spring MVC,Spring,MyBatis时所遇到的问题以及如何解决
    RustDay06------Exercise[91-100]
    图像处理:坐标变换
  • 原文地址:https://blog.csdn.net/HugMua/article/details/125914965