首页 › programming › 从锁到Actor:并发模型演进

从锁到Actor:并发模型演进七强精读

本期概述

并发(concurrency)是 2026 年编程领域最"老又新"的话题。老,是因为从 Dijkstra 1965 年提出信号量至今已逾六十年;新,是因为多核普及、AI 推理工作负载爆炸、以及 Java 虚拟线程、Swift 结构化并发、Rust async 的相继成熟,让"如何让程序同时做很多事而不出 bug"重新成为工程焦点。

本轮聚焦 programming(编程与开发) 分类,避开了前几轮已覆盖的 Rust 语法、WASM、前端框架、AI 智能体等方向,专攻一条贯穿始终的主线:并发协调模型的演进——从共享内存加锁、无锁原子操作,到 Actor、CSP、async/await,最终收敛到"结构化并发(Structured Concurrency)"。

本文精选 7 个高质量 YouTube 内容,覆盖从底层协调成本(Jon Gjengset)、Actor/OTP 哲学(Francesco Cesarini)、async 心智模型(Zainab Ali),到 Swift 与 Java 两套结构化并发实现,再到 Actor vs CSP 的范式对比与 Fireship 的入门速览。读者将获得一张可落地的"选型地图"。

频道与内容对比

# 频道/演讲者 内容主题 范式 深度 适合人群
1 Jon Gjengset (@jonhoo) The Cost of Concurrency Coordination 锁/原子/通道成本 极深 Rust/系统编程进阶
2 Francesco Cesarini Thinking Concurrency: Erlang/Elixir Actor / OTP 深 后端/分布式
3 Zainab Ali The Currents of Concurrency (Async Rust) async/await 心智模型 中深 Rust 学习者
4 Apple WWDC25 Embracing Swift Concurrency 结构化并发+Actor 中 iOS/macOS 开发
5 Java 25 视频 Structured Concurrency in Action 虚拟线程+结构化并发 中 JVM 后端
6 综合 Comparing Actor Model & CSP (Elixir & Clojure) Actor vs CSP 中 语言选型者
7 Fireship 并发概念速览(100 秒系列) 全景入门 浅 零基础/速览

一、Jon Gjengset:并发协调的真实代价

频道:@jonhoo(YouTube)|订阅约 25 万+|推荐内容:《The Cost of Concurrency Coordination》(Jane Street 版长讲)

Jon Gjengset 是 Rust 社区公认的"深水区向导",其 Crust of Rust 系列几乎是进阶 Rustacean 的必经之路。这场《The Cost of Concurrency Coordination》是他近期的旗舰演讲,核心论点只有一个:并发不是免费的,而"协调"本身才是真正昂贵的部分。

大多数教程讲并发只讲"如何避免数据竞争",Jon 却把聚光灯打在 Mutex、RwLock、原子操作、channel 这些原语的开销上。他用实测数据展示:一把看似无害的锁,在核数增多、缓存行(cache line)被反复抢占时,吞吐量不升反降——这就是"协调成本"(coordination cost)。关键洞察有三:第一,加锁的代价不是 CPU 指令,而是缓存一致性协议带来的跨核同步;第二,无锁(lock-free)并不等于"快",过度乐观的 CAS 自旋会在高争用下劣化为总线风暴;第三,消息传递虽优雅,但 channel 仍有拷贝与调度开销,必须按工作负载特征选型。

实用价值:写高并发代码前先问"我到底在协调什么、多频繁"。适合做基础设施、数据库、网络栈的系统工程师,以及任何在 Rust 中纠结"用 Mutex 还是 channel"的人。

二、Francesco Cesarini:Actor 与"让它崩"哲学

视频:《Thinking Concurrency: Dwelling in Erlang and Elixir》|YouTube 可搜

Francesco Cesarini 是 Erlang 生态元老级人物(Erlang Solutions 联合创始人),讲 Actor 模型有"祖师爷亲自下场"的厚度。这场演讲的核心不是语法,而是 Erlang/OTP 设计哲学的"三观重塑"。

Actor 模型把并发单元抽象为一一个个隔离的进程,每个进程拥有私有状态,彼此只通过异步消息通信——没有共享内存,自然没有数据竞争,也就不需要锁。Cesarini 反复强调 Erlang 的两大法宝:一是"超轻量进程"(数百万级,由虚拟机调度而非操作系统),二是监督树(supervision tree)支撑的"let it crash(让它崩)"文化。传统思路是穷尽心力防止错误,OTP 反其道:进程崩了不要紧,监督者自动按策略重启,系统反而获得极高容错性。这正是爱立信交换机、WhatsApp 当年能以极少服务器扛住海量并发的根因。

实用价值:理解 Actor 后,你会重新审视"用锁保护共享状态"这条路的天花板。适合构建聊天、IM、物联网、电信级长连接后端的开发者,也是理解 Akka、Elixir、乃至分布式 Actor 框架(如 Proto Actor)的钥匙。

三、Zainab Ali:用"水流"理解 async Rust

演讲:《The Currents of Concurrency: Reasoning with Async Rust》|约 54 分钟

async/await 是当代并发最流行的语法糖,却也最容易让人踩坑:明明没有线程切换,为什么还会"死锁"?为什么 Future 不 .await 就不执行?Zainab Ali 的这场演讲给出了一个绝佳的心智模型——把 async 程序想象成水流(currents)。

她把抽象拆解为三层:第一层,Future 是一个状态机,描述"未来可能完成的工作",它惰性(lazy),必须被"驱动"才会推进;第二层,执行器(executor)是水泵,负责把多个 Future 轮转调度;第三层,.await 是汇合点,让水流在此等待。关键洞察:async 代码一旦涉及 Send 边界跨线程传递,或持有锁跨 .await 点,就会埋下死锁与性能地雷。她特别指出"在 async 上下文中持锁"是 Rust 异步第一杀手——运行时可能把任务切走,锁却一直攥在手里,其他任务全部阻塞。

实用价值:建立"async 是协作式调度"的直觉,从根上理解 .await、Send、Sync 的约束。适合所有用 Rust/Tokio/async-std 的开发者,也适用于理解 JS、Python asyncio、C# 中类似的协作式并发陷阱。

四、Apple WWDC25:Swift 结构化并发正式收口

链接:developer.apple.com/videos/play/wwdc2025/268/《Embracing Swift Concurrency》

WWDC25 这场会话标志着 Swift 并发模型走向成熟稳定。Swift 自 5.5 引入 async/await 与 Actor 后,今年进一步把"结构化并发(Structured Concurrency)"打磨成推荐范式。Apple 的叙事很清晰:并发代码的 bug,八成来自"任务逃逸"——一个异步任务被 spawn 出去后,其生命周期与父作用域脱钩,导致取消信号传不到、错误无人收、资源泄漏。

Swift 的解法是用 async let、Task Group(withTaskGroup)和 Task 的结构化变体,把子任务绑定到父作用域:作用域退出前,所有子任务必须完成或被取消,错误会被向上传播。配合 actor 类型保证内部状态访问的串行化,开发者几乎可以告别手动加锁。Apple 还强调了"actor 隔离(actor isolation)"与 Sendable 协议的配合——编译器在编译期就拦下不安全的数据共享。

实用价值:iOS/macOS/watchOS/xrOS 开发者的"新地基"。理解结构化并发后,UI 卡顿、后台任务泄漏、取消不响应等老大难问题都能系统化解决。适合全体 Apple 平台工程师。

五、Java 25:虚拟线程 + 结构化并发双剑合璧

视频:《Structured Concurrency in Action》(Java 25 第五次预览)

Java 是"老牌并发语言"中变革最激进的。从 Java 21 虚拟线程(Virtual Thread / Project Loom)颠覆"一线程一 OS 线程"的旧模型,到 Java 25 把结构化并发 API 推进到第五次预览(变化颇多),JVM 后端正在经历一场静默革命。

虚拟线程让"一请求一线程"的阻塞式写法重新变得高效——百万级虚拟线程由 JVM 调度,阻塞调用不再占用 OS 线程。但仅有虚拟线程还不够:如果没有结构化并发,异步任务依然会逃逸。Java 25 的 StructuredTaskScope 让你能声明式地"打开一个作用域、派生子任务、统一等待与取消"。两个杀手级模式:ShutdownOnFailure(任一失败即取消其余)与 ShutdownOnSuccess(首个成功即取消其余),把过去几十行 Future 编排代码压缩成几行。配合作用域退出自动取消,资源泄漏与线程泄漏被彻底堵住。

实用价值:Java 后端开发者从"回调地狱 / CompletableFuture 套娃"解放出来的关键。适合所有写微服务、网关、高并发接口的 JVM 工程师,尤其是还在用 RxJava/Reactor 的团队——结构化并发很可能让响应式编程的复杂度不再必要。

六、Actor vs CSP:两种消息传递的范式分野

视频:《Comparing the Actor Model & CSP Concurrency with Elixir & Clojure》|YouTube 可搜

很多人把 Actor 和 CSP(Communicating Sequential Processes)混为一谈,因为它们都是"消息传递"。这场对比视频的价值,正在于把两者的语义差异讲透。

核心区别在消息的"耦合度"与"归属":Actor 模型中,消息被投递到特定 Actor 的邮箱(mailbox),发送方必须知道接收方是谁,是"点名送达";CSP 模型中,通信通过匿名通道(channel)进行,发送方与接收方在通道上汇合,彼此不必知道对方身份,是"管道汇合"。由此衍生设计哲学差异:Actor 天然面向有状态实体(适合分布式对象、监督树),CSP 天然面向数据流流水线(Go 的 goroutine + channel 即典型)。视频用 Elixir(Actor)与 Clojure core.async(CSP)做对照演示,清晰展示:同样的问题,两套模型给出截然不同但都优雅的解法。

实用价值:语言/架构选型时的"第一性原理"判断。你是建模"有状态的参与者"(用 Actor),还是建模"流动的数据管道"(用 CSP)?适合技术负责人、做语言选型或微服务通信范式决策的工程师。

七、Fireship:百秒看懂并发全貌

频道:Fireship(YouTube)|订阅约 380 万+|"100 Seconds of Code"并发系列

在一众深度内容之外,需要一个"快门"来建立全局印象,Fireship 是不二之选。作为全球最受欢迎的编程娱乐向频道之一,它用极致压缩的节奏,把 Go channels、Rust async、线程池、事件循环等概念各用百秒讲清。

它的价值不在"深",而在降低门槛与保持敏锐。对于非后端出身的全栈、前端、数据科学家,Fireship 提供了一张"术语地图":知道 Actor、CSP、Promise、coroutine、green thread 分别指什么、各属哪个生态。关键洞察式表达(如"async 不是多线程,是耐心等待的艺术")常常一语中的。但要注意:百秒内容是"引子"而非"正文",真正落地仍需回到前六个深度资源。

实用价值:建立并发概念的"全局索引",快速判断某个话题值不值得深入。适合零基础入门者、需要跨界了解后端概念的前端/数据从业者,以及想快速跟上新语言并发特性的开发者。


并发模型知识图谱

下图刻画并发问题从根源到解法的演进路径,以及各范式如何最终向"结构化并发"收敛:

flowchart TD
    ROOT["并发根源:共享可变状态 + 时序不确定"] --> Q{"如何协调访问?"}
    Q -->|"共享内存 + 锁"| LOCK["互斥/读写锁<br/>Mutex · RwLock"]
    Q -->|"无锁原子"| LF["Lock-free<br/>CAS · 原子操作"]
    Q -->|"消息传递"| MP["Message Passing"]
    Q -->|"异步任务"| ASYNC["Async/Await<br/>事件循环 / Future"]
    Q -->|"事务内存"| STM["STM 软件事务内存"]
    MP --> ACTOR["Actor 模型<br/>Erlang · Elixir · Akka · Swift actor"]
    MP --> CSP["CSP 模型<br/>Go · Clojure core.async"]
    LOCK & LF & ACTOR & CSP & ASYNC --> SC["结构化并发 Structured Concurrency<br/>Swift · Java 25 · Kotlin · Python"]
    SC --> GOAL["目标:可组合、可取消、不泄漏、易推理"]
    style SC fill:#cfe,stroke:#369,stroke-width:2px
    style GOAL fill:#fec,stroke:#c63,stroke-width:2px

结构化并发与传统"fire-and-forget"的本质差异,在于作用域与生命周期的绑定:

flowchart LR
    subgraph NS["❌ 非结构化:任务逃逸"]
        direction TB
        P1["父作用域"] -. spawn .-> C1["子任务:生命周期不可控"]
        C1 -. 取消信号丢失/错误无人收 .-> LK["泄漏"]
    end
    subgraph SS["✅ 结构化:作用域绑定"]
        direction TB
        P2["父作用域 (Scope)"] ==>|await| C2["子任务 1"]
        P2 ==>|await| C3["子任务 2"]
        C2 & C2 ==> R["作用域退出前<br/>全部完成或统一取消"]
    end
    style SS fill:#eafaea,stroke:#3a3
    style NS fill:#fdecea,stroke:#c33

选型建议:什么时候用哪一套

一条通用经验法则:能用结构化并发就不要裸 spawn,能用消息传递就不要共享内存加锁,能用语言原生并发原语就不要手写线程池。

延伸推荐

  1. Computerphile(YouTube,订阅约 280 万+)——学术风格讲解死锁、竞态、并行架构基础概念,适合补理论底子。
  2. Dave Farley / Continuous Delivery——从软件工程视角讲并发设计的可测试性与工程纪律。
  3. The Cherno(C++)与 Casey Muratori(Handmade Hero)——从内存模型、缓存行、伪共享(false sharing)讲并发性能的硬件根因。
  4. Reducible——算法与系统可视化,含并发数据结构(无锁队列等)的动画讲解。
  5. rust.conference / RustConf 历年演讲合集——async、tokio、并发原语的实战深讲宝库。

参考来源

  1. Jon Gjengset - YouTube (@jonhoo) — Rust 深度教学,《The Cost of Concurrency Coordination》演讲出处
  2. Thinking Concurrency: Dwelling in Erlang and Elixir - Francesco Cesarini — Actor/OTP 与 let it crash 哲学
  3. Embracing Swift Concurrency - WWDC25 (Apple Developer) — Swift 结构化并发与 actor 官方讲解
  4. Structured Concurrency in Action (Java 25) — Java 25 第五次预览结构化并发 API
  5. Comparing the Actor Model & CSP Concurrency (Elixir & Clojure) — Actor 与 CSP 语义差异对比

本文由「51学通信」技术团队出品。51学通信由通信行业18年老兵爱卫生(微信ID: gprshome201101)维护,聚焦5G/6G核心网、3GPP标准解读、通信前沿技术深度分析。 出版作品有《5G核心网原理与实践》《IMS原理与实践》等4本通信专业书籍。知识星球「51学通信」提供深度技术答疑和行业洞察。

[!tip] 51学通信知识星球 星主:爱卫生(微信:gprshome201101)——公众号「51学通信」创办者,19 年通信行业运维与讲师经验,著有《GPRS网络信令实例详解》《EPC原理与实践》《5G核心网原理与实践》三本纸质书(各大电商平台有售)。 星球定位:深耕 5G 核心网、IMS、NFV/AI、云原生等 ICT 领域,主打运维岗位与信令分析。 当前规模:5200 篇主题 / 990 个回答,198 元/年。 加入福利:加入星球后请加爱卫生微信,拉您进知识星球年度陪伴与答疑群——不限量回复您的各种问题,另有群内分享。 AI 加持:51学通信知识星球已作为 skill 接入 WorkBuddy,使用 deepseek-4-flash 在海量星球帖子中精准找贴、找视频、找 FAQ 和案例,做总结、找文档和 PPT 等场景全覆盖。

51学通信知识星球海报-扫码加入