205-协程与 Flow 入门
05 协程与 Flow 入门这一章解决“理解协程到底是什么、和线程什么关系,能写出基本的后台加载 + 切主线程,并理解 Flow 冷流”。这里只做入门,深挖(调度细节、异常传播、背压、测试)放在第 08 模块threading-and-coroutines。1. 协程和线程的关系先建立最重要的直觉:协程不是线程,是运行在线程之上的、可挂起的任务。维度线程(Thread)协程(Coroutine)由谁调度操作系统Kotlin 运行时 + 协程库成本重(MB 级栈、内核切换)轻(对象级别,可同时几万个)阻塞代价占住一个线程挂起时释放线程去干别的关系协程在线程上执行一个线程可轮流跑很多协程关键点:当协程遇到suspend挂起(如等网络返回)时,它会让出当前线程,线程去执行别的协程;等结果就绪后,协程再被恢复到某个线程上继续。这就是协程“用少量线程支撑大量并发”的原理,也是它比“一个任务一个线程”高效的原因。suspend挂起的是协程,不是线程。这是初学最容易搞混的点。2. suspend 函数suspend标记“这个函数可能会挂起,必须在协程或另一个 suspend 函数里调用”。suspendfunloadUser(id:Long):User{returnapi.fetchUser(id)// 网络请求,挂起等待,不阻塞线程}普通函数不能直接调suspend函数。suspend函数写起来像同步代码(顺序、无回调),但执行是非阻塞的。suspendfunloadProfile(id:Long):Profile{valuser=loadUser(id)// 顺序写,但每步可挂起valorders=loadOrders(id)returnProfile(user,orders)}这就是协程最大的卖点:用同步的写法表达异步逻辑,消灭回调地狱。3. CoroutineScope 与启动协程必须在一个CoroutineScope里启动。scope 管理协程的生命周期——scope 取消时,里面所有协程一起取消。scope.launch{valuser=loadUser(1)updateUi