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 调度切换线程。

相关推荐
恋猫de小郭21 分钟前
AI Agent 开发究竟是啥?如何用 AI 开发 Agent ?深入浅出给你一套概念
android·前端·ai编程
黄林晴35 分钟前
Android 17 正式发布!target 37 一大批旧代码直接不能用了
android
Carson带你学Android1 小时前
Android 17 正式发布:AI 终于成了系统能力
android·前端·ai编程
三少爷的鞋1 小时前
当 UseCase 开始长期监听,它可能已经不是 UseCase 了
android
恋猫de小郭14 小时前
Android 限制侧载新进展,谷歌联合国内厂商推验证计划
android·前端·flutter
恋猫de小郭14 小时前
解读 Android 17 全新内存限制,有没有“豁免”后门?
android·前端·flutter
贾艺驰17 小时前
实战Android Framework: 新增一个系统权限
android
alexhilton1 天前
使用Android Archive进行打包
android·kotlin·android jetpack
badhope1 天前
做了几年安卓开发,这些坑我帮你踩过了
android·android studio
逐光老顽童3 天前
Java 与 Kotlin 混合开发避坑指南:30 个真实案例实录
android·kotlin