Appearance
并发与运行时底座
模块定位
这个模块不是按语言平铺罗列知识点,而是用一条统一主线建立运行时心智:
先理解“代码由谁承载、挂起后现场放哪、恢复时靠什么继续跑”,再把 Java、Kotlin、Dart/Flutter、JS、Go 放回同一张地图里。
它是后续理解生命周期、后台任务、状态管理、性能分析与排障的底层前置模块。
你会在这里建立什么判断力
建议带着下面这些问题阅读,每看完一个分组,都回头检查自己能不能用代码、调用栈或运行现象解释它:
- 线程到底是什么,它和任务是什么关系?
- 一句话答:线程是 OS / JVM 层的执行载体;任务是“要跑的代码”,最终必须落在某条线程上执行,二者是“执行单元 vs 要执行的活”的关系。
- 协程为什么不是线程,只是“更轻量的线程”这种说法哪里不对?
- 一句话答:协程是可挂起任务(状态机 + Continuation),不创建也不独占线程,恢复时才借线程跑;“更轻量线程”容易让人误以为它自带独立执行栈和调度。
- Future 为什么不自动等于并发能力?
- 一句话答:
Future只是结果句柄 / 调度单元,默认在当前线程 / isolate 排队,不自动创建并行执行单元。
- 一句话答:
suspend/await挂起后,执行现场到底保存在哪里?- 一句话答:保存在堆上的 Continuation / 状态机对象里(
label+ 局部变量字段),不是占着线程栈。
- 一句话答:保存在堆上的 Continuation / 状态机对象里(
- isolate 为什么是“隔离并发”,而不是共享内存并发?
- 一句话答:每个 isolate 有独立堆和事件循环,不共享对象,靠消息传递协作,天然没有共享可变状态的数据竞争。
- event loop 到底在调度什么,microtask / event queue 差异是什么?
- 一句话答:调度“下一个要执行的代码段”;microtask 在当前同步段结束后先清空,event queue 放到下一轮事件循环,microtask 优先。
- Java / Kotlin / Dart / JS / Go 各自最适合解决哪类并发问题?
- 一句话答:Java 共享内存 + 线程池(锁 / 原子类);Kotlin 结构化并发 + 生命周期治理;Dart / JS 单线程事件循环 + isolate / Worker 搬走 CPU 重活;Go 轻量 goroutine + channel,面向服务端高并发。
模块导航总览
阅读方式:先走运行时入口,再沿主线进入 Java → Kotlin → Dart/Flutter,最后用 JS / Go 做对照校准。
一、运行时入口:先把地图搭起来
这是整个模块的起点。先把线程、栈、堆、Continuation、Future、isolate、event loop 放回统一坐标系,再去看具体语言的实现差异。
- 运行时承载模型入口
- Android 架构总览:分层、线程模型、组件系统与 UI 范式
- Android 主线程消息循环:Looper / Handler / MessageQueue
- Android Binder IPC 机制与跨进程通信
- Android ANR 触发机制、排障定位与防范
适合解决的问题
- 不再把“线程 / 协程 / Future / isolate / event loop / Android 主线程”混成一团
- 知道 Android 整体平台分层,以及 Looper / Binder / 生命周期 / 渲染各自落在哪层
- 把 Android 主线程的 Looper / Handler 也放进“单线程消息调度”的同一张图里,和 JS / Dart 的 event loop 对齐
二、Java 主线:先建立共享内存并发的基本盘
Java 主线负责建立最硬的底层心智:任务如何交给线程执行、共享状态为什么会出问题、可见性/原子性/有序性如何约束结果。
如果这一段吃透,后面的 Kotlin 协程、Dart isolate、JS event loop、Go goroutine 都更容易定位。
2.1 总览页
2.2 按学习顺序展开的专题
- Thread / Runnable / Callable / Future
- 先分清“任务是什么、线程是什么、Future 只是结果句柄还是什么”。
- ExecutorService / 线程池
- 再看任务如何被调度、线程为什么要复用、线程池参数如何影响行为。
- synchronized / Lock / volatile
- 然后进入共享状态保护,建立锁与可见性的第一层判断力。
- Atomic* / CAS / LongAdder
- 再补无锁原语与热点竞争下的优化手段。
- JMM:happens-before / 安全发布
- 这一步把“为什么代码看起来对、运行结果却不稳定”讲清楚。
- 死锁 / 活锁 / 竞态定位
- 最后进入问题定位与排障,把前面的机制串回真实工程事故。
- ConcurrentHashMap(CHM)速览
- 作为常见并发容器补充,对照“高频 API 背后用了哪些并发策略”。
层级说明:Java 总览页负责概念地图;专题页负责机制、选型、代码与排障展开。
三、Kotlin 主线:在线程之上理解挂起、恢复与取消传播
Kotlin 主线不是替代 Java 并发,而是在 JVM 线程之上建立任务编排、挂起恢复、结构化并发、取消传播的第二层心智。
重点不是把协程当成“更轻线程”,而是理解:协程如何复用线程、如何保存现场、如何把取消和作用域变成可组合的工程能力。
3.1 总览页
3.2 按学习顺序展开的专题
- Kotlin Dispatchers / 上下文切换 / 协程构建器
- 先建立“协程跑在哪、是谁决定线程切换”的判断。
- Kotlin Scope / Job / 取消传播 / 状态流
- 再理解结构化并发、父子关系与取消传播为什么重要。
- Kotlin Mutex / 共享状态保护
- 最后回到共享状态问题,理解协程世界里如何做互斥与状态收敛。
- Kotlin Flow:冷流数据管道 / 背压 / flowOn
- 再补协程数据流的另一半:冷流、suspend 背压与 flowOn 切上下文。
- actor 风格(建议后续补单独对照页)
- 当前作为后续扩展点,暂不在本模块首页展开。
层级说明:Kotlin 总览先回答“协程到底在运行时怎么落位”;专题页再拆调度、作用域、取消、共享状态保护。
四、Dart / Flutter 主线:先分清调度,再分清真正并发
这一组建议结合 Flutter 日常开发去理解:
Future很多时候只是异步调度结果,不是“开了新线程”- event loop 决定了回调何时恢复
- isolate 才是 Dart 真正意义上的并发隔离
- Flutter 中
compute只是 isolate 能力的一种落地方式
4.1 总览页
- Dart 并发总览:Future / event loop / isolate
- Flutter 总览:runtime / framework / engine / embedder / plugin / platform channel
4.2 按学习顺序展开的专题
- Dart 并发总览:Future / event loop / isolate
- 先做工具选型:普通异步等待用什么、单次 CPU 重活该不该上
compute/Isolate.run、什么时候要升级到Isolate.spawn。
- 先做工具选型:普通异步等待用什么、单次 CPU 重活该不该上
- Dart 事件循环与队列:event loop / microtask / event queue
- 再把主 isolate 上的调度顺序看清,解决“为什么输出顺序和直觉不一样、为什么某些代码会卡 UI”。
- Dart Future / await:调度、恢复与顺序错觉
- 接着理解
await恢复点、then()continuation、Future 与 Java/Kotlin 对应物的边界。
- 接着理解
- Dart isolate / Flutter compute:真正的并发隔离
- 再进入 Flutter 场景:大 JSON、图片压缩、相机帧处理何时该搬离 UI isolate,
compute有哪些限制和成本。
- 再进入 Flutter 场景:大 JSON、图片压缩、相机帧处理何时该搬离 UI isolate,
- Dart Isolate 消息传递:SendPort / ReceivePort
- 最后进入长期后台 worker:理解隔离并发的通信机制、可发送对象边界,以及何时从
compute升级到Isolate.spawn。
- 最后进入长期后台 worker:理解隔离并发的通信机制、可发送对象边界,以及何时从
- Dart Stream:异步数据序列 / 生成器 / 背压
- 补上 Dart 异步的另一条腿:多次回调的数据流与手动背压。
- Flutter 总览:runtime / framework / engine / embedder / plugin / platform channel
- 在进入引擎线程与平台桥接前,先把 Flutter 的整体分层、跨平台成立条件与 Android 映射关系放回一张图里。
- Flutter 引擎线程模型:UI isolate / raster / platform / IO
- 收口到 Flutter:卡顿先归因“哪条线程在忙”,别只优化 Dart 侧。
Dart / Flutter 最短推荐路径:
- 只想先建立主线:
03 → 09 → 10 → 11 → 14 - 只想解决 Flutter 卡顿归因:
09 → 11 → 14-flutter-engine-threads - 只想判断“该不该上 isolate”:先看
03的决策表,再看11与14
层级说明:Dart 总览先搭 Future / event loop / isolate 的执行地图;Flutter 总览再把 framework / engine / embedder / plugin 关系补齐;专题页分别解决队列、恢复语义、后台计算、消息通信与引擎线程边界。
五、JS / Go 对照:用不同并发哲学校准主线理解
这一组不作为主线深挖,而是作为对照系帮助你校准前面的判断:
- JS 代表典型的 event loop + callback / Promise / Worker 模型
- Go 代表 goroutine + channel + context 的 CSP 风格并发模型
把它们放在最后看,更容易明确“它们和 Java / Kotlin / Dart 到底哪里像、哪里根本不同”。
- JS Promise / event loop / Worker
- Go goroutine / channel / context
- 跨语言运行时并发总对照:Java / Kotlin / Dart / JS / Go
推荐阅读顺序
如果你是按模块系统复习,建议严格按下面顺序推进:
- 运行时承载模型入口
- Android 架构总览:分层、线程模型、组件系统与 UI 范式(先把 Android 这条宿主主线放回整张运行时地图)
- Android 主线程消息循环:Looper / Handler / MessageQueue(Android 主线程的调度机制,先于语言主线)
- Java 并发模型总览
- Java 专题主线:
- Kotlin 协程并发总览
- Kotlin 专题主线:
- Dart / Flutter 主线:
- Dart 并发总览:Future / event loop / isolate
- Dart 事件循环与队列:event loop / microtask / event queue
- Dart Future / await:调度、恢复与顺序错觉
- Dart isolate / Flutter compute:真正的并发隔离
- Dart Isolate 消息传递:SendPort / ReceivePort
- Dart Stream:异步数据序列 / 生成器 / 背压
- Flutter 总览:runtime / framework / engine / embedder / plugin / platform channel
- Flutter 引擎线程模型:UI isolate / raster / platform / IO
- JS Promise / event loop / Worker
- Go goroutine / channel / context
- 跨语言运行时并发总对照:Java / Kotlin / Dart / JS / Go
对应 labs 入口
这些入口对应“看完概念后,立刻动手验证运行现象”的实验层。
- Java:
labs/java/runtime-concurrency/(当前模块首页保留目录入口,后续可继续补具体 lab README / 源码直链) - Kotlin:coroutine-execution-flow(最小 Main → IO → Main 执行链)
- Kotlin:coroutine-mutex-stateflow(Mutex / StateFlow / SharedFlow)
- Dart:dart-event-loop-isolate
- Dart:dart-stream-async-generator(async* / StreamController / 背压)
- Dart:dart-isolate-message-passing(SendPort / 深拷贝 / 双向通信)
- Android:looper-handler-demo(消息循环 / HandlerThread)
- Android:binder-messenger-demo(Binder / Messenger 双向)
- Android:anr-mechanism-demo(ANR 触发与诊断)
- JS / Node:后续建议补
labs/node/runtime-concurrency/ - Go:后续建议补
labs/go/runtime-concurrency/
这页怎么用
- 第一次系统复习:严格按“运行时入口 → Java → Kotlin → Dart/Flutter → JS/Go 对照”的顺序读
- 查缺补漏:先回到对应主线总览,再进入专题页,不建议直接从零散专题反向拼图
- 带实验学习:每读完一个主线分组,就去对应 labs 看一次输出顺序、线程切换、取消传播、状态竞争或 isolate 行为
备注
这个模块首页现在承担的是“导航页”职责:重点是把总览层、专题层、推荐顺序和实验入口明确分开。后续如果继续扩展,更适合补跨语言总对照表与缺失 labs,而不是继续把首页堆成平铺清单。