Kotlin 官网为什么不再强调“协程是轻量级线程”了?

135 阅读3分钟

你还在说"协程是轻量级线程"吗?Kotlin 官方已经不这么定义了。


一、早期的说法:协程 = 轻量级线程

Kotlin 1.1 刚推出协程时,官方文档里直接写着:

"Coroutines are light-weight threads."

Kotlin 1.1 Coroutines 官方文档

当时这样宣传完全合理。那几年大家还在被 Thread、AsyncTask、RxJava Scheduler、callback hell 折磨,Kotlin 需要一个最容易传播的比喻:

  • 线程很贵(系统调用、栈内存、上下文切换)
  • 协程很便宜(几乎零成本创建,轻松开几十万个)

于是"轻量级线程"成了最广为流传的定义。


二、现在官方怎么说的?

打开当前版本的 Kotlin Coroutines Basics 文档,你会发现措辞明显变了:

旧文档(1.1 时期)新文档(当前)
Coroutines are light-weight threads.A coroutine is an instance of a suspendable computation.
强调:lightweight、thread强调:suspendnon-blockingstructured concurrency

官方不再把协程定义为"线程的轻量版",而是重新定义为:

一段可挂起的计算(suspendable computation)。

核心词从 thread 变成了 suspend


三、为什么要改?因为"轻量级线程"容易让人误解

误解一:协程就是线程

协程不是 OS Thread,不是 JVM Thread,不参与 CPU 调度。它的底层是 Continuation(续体)+ 状态机,跟线程是完全不同的抽象层次。

误解二:协程的价值是"性能"

很多人以为协程解决的是线程性能问题。实际上,协程的首要价值是让异步代码变得可读,资源效率是附带的收益。

回调地狱:

image.png

协程写法:

image.png

代码从"跳来跳去"变回了"从上往下"。这才是协程最大的胜利。


四、协程的底层到底是什么?

Kotlin 编译器会把 suspend 函数改写成状态机

源代码:

image.png

编译后的伪代码(简化版):

image.png

关键点:

  • suspend 的本质是保存当前执行状态,然后 return
  • 恢复时从上次的 label 继续执行
  • 整个过程不需要额外的线程或线程栈

所以有人说:

Coroutine is not a lightweight thread. Coroutine is a lightweight continuation.

协程真正便宜的不是"线程变轻了",而是 continuation 本身就极轻——只需要保存几个局部变量和一个状态标记。


五、现在官方真正强调的东西

1. Structured Concurrency(结构化并发)

image.png

父协程取消 → 子协程全部取消。不会有"野协程"泄漏。

2. Cancellation Propagation(协作式取消)

image.png

3. Suspend 语义

image.png

suspend 关键字告诉调用者:"这个函数可能异步挂起,但你可以像同步代码一样调用它。" 这是 Kotlin 最大的语言级价值。

4. Flow / Channel

完整的异步数据流生态,已经远超"轻量级线程"的范畴。


六、总结

Kotlin 官方并没有完全删除"lightweight thread"这个说法,但已经不再把它作为核心定义

因为协程的本质不是:

  • 更轻的线程

而是:

  • Suspend(可挂起)
  • Continuation(续体/状态机)
  • Structured Concurrency(结构化并发)
  • Non-blocking(非阻塞)
  • Async Semantics(异步语义)

所以,更准确的理解应该是:

协程不是轻量级线程,而是一种语言级的可挂起并发模型。