Kotlin 协程 Coroutine

1、什么是协程?和线程有什么区别

答案

协程是轻量级线程 ,基于线程封装,由语言层调度,不是操作系统调度。

区别:

  1. 线程由 OS 调度、开销大;协程开销极小、可开上万个。
  2. 线程是抢占式 ;协程是协作式,主动挂起、恢复。
  3. 协程可非阻塞挂起,不阻塞当前线程。
  4. 协程自带上下文、作用域、生命周期,更适合 Android 异步开发。

2、协程的优点

答案

  1. 轻量、占用资源少,支持大量并发;
  2. 用同步写法写异步代码,告别嵌套回调;
  3. 自带作用域,可统一取消、防泄漏
  4. 灵活切换调度线程(主线程 / 子线程);
  5. 配合 Flow、Jetpack 生态适配更好。

3、什么是挂起函数 suspend?作用是什么

答案

suspend 修饰的函数是挂起函数

特点:

  1. 只能在协程或其他挂起函数中调用;
  2. 不会阻塞线程,只是挂起当前协程,让出线程执行其他任务;
  3. 耗时结束后自动恢复继续执行。

4、suspend 底层原理

答案

Kotlin 编译器把挂起函数编译成 状态机,把代码切分成多个状态片段;

挂起点保存上下文,恢复时从对应状态继续执行,实现无回调异步。

5、协程三大核心:协程作用域、调度器、生命周期

答案

  • 作用域 Scope:管理协程生命周期,统一取消、控制启停;
  • 调度器 Dispatcher:指定协程跑在哪个线程;
  • Job:协程任务句柄,可取消、监听完成状态。

6、四大调度器 Dispatcher 区别

答案

  • Dispatcher.Main:主线程,更新 UI;
  • Dispatcher.IO:子线程,适合网络、文件、数据库 IO;
  • Dispatcher.Default :子线程,适合CPU 密集型复杂计算;
  • Dispatcher.Unconfined:不指定线程,随上下文执行,几乎不用。

7、常用协程作用域有哪些

答案

  1. GlobalScope :全局作用域,生命周期跟 App 一致,不推荐,容易泄漏;
  2. viewModelScope :ViewModel 自带,ViewModel 销毁自动取消协程,防泄漏;
  3. lifecycleScope:Activity/Fragment 自带,页面销毁自动取消;
  4. 自定义 CoroutineScope 自己管理生命周期。

8、为什么不推荐用 GlobalScope

答案

GlobalScope 生命周期贯穿整个 App,页面退出无法自动取消;里面的网络、延时任务还在后台跑,极易造成内存泄漏、浪费资源

9、launch 和 async 区别

答案

  • launch :只执行任务,无返回值,返回 Job;
  • async :有返回值,返回 Deferred ,可用 await() 拿结果;适合需要获取异步返回值的场景。

10、await () 作用

答案

等待 async 协程执行完成,挂起当前协程,拿到返回结果;不会阻塞线程,只是协程挂起。

11、协程怎么取消?取消原理

答案

通过 Job.cancel () 取消协程;

协程在挂起点 会响应取消,抛出 CancellationException;作用域取消后,内部所有子协程全部级联取消

12、协程异常怎么处理?CoroutineExceptionHandler

答案

  1. 单个协程内部用 try-catch 包裹挂起函数;
  2. 全局统一异常用 CoroutineExceptionHandler
  3. launch 默认异常会崩溃;async 异常在 await 时才抛出。

13、协程结构化并发

结构化并发:子协程依附父协程作用域,父子生命周期绑定,自动取消、自动异常传递,杜绝协程泄漏。

核心三点

  1. 父子协程关系 协程有父子层级,子协程继承父Scope、Dispatcher、异常策略
  2. 结构化取消 父作用域一取消,所有子协程跟着全部级联取消,不用手动一个个解绑,天然防内存泄漏。
  3. 异常自动传播子协程抛异常,会向上传给父协程,统一捕获处理,不会静默崩溃、丢异常。

14、协程的启动模式几种

四种枚举

CoroutineStart 一共四种:DEFAULT、LAZY、ATOMIC、UNDISPATCHED

逐个极简解释

1、DEFAULT(默认)

立刻根据调度器调度执行,排队进入对应线程池,标准常规启动。

2、LAZY(懒启动)

不会自动执行 ,需要手动调用 start() / join() 才开始跑;适合需要延迟触发、手动控制时机的场景。

3、ATOMIC

立即在当前线程原子式启动 ,不可取消;在挂起之前,无法被取消,执行到第一个挂起点才响应取消。

4、UNDISPATCHED

直接在当前线程立刻执行 ,不切调度器;直到遇到第一个 suspend 挂起点,之后才按 Dispatcher 调度切换线程。

相关推荐
爱笑鱼2 小时前
Binder(八):远端进程死了,BinderProxy 为什么还能收到通知?
android
Android-Flutter2 小时前
Kotlin 冷流与热流详解
android·kotlin
zhangphil2 小时前
Android ContentProvider/ContentResolver读图片,跨进程 IPC慢
android
yueqc13 小时前
Android .so 文件压缩
android·so·包体积
龚礼鹏3 小时前
深入解析 Android Automotive (AAOS) 启动流程与 CarService 核心机制(基于 Android 16 最新源码视角)
android
rosmis3 小时前
agent各指标定义
android·java·开发语言
风样滴男人哟4 小时前
PHP特性之反射类ReflectionClass机制
android·开发语言·php
小孔龙5 小时前
RenderNode 与 DisplayList:Android 硬件加速的绘制记录与复用
android·性能优化
qizayaoshuap6 小时前
鸿蒙 ArkTS 实战:搜索列表 城市实时过滤(示例 94)
android·华为·harmonyos
朝星6 小时前
Framework筑基之Handler消息机制5(应用层)
android