Java有协程吗?
“这个问题挺经典的,其实背后是在问高并发模型的选择。我按我的理解分层来说:
🔹 结论先行
在很长一段时间里,Java 没有官方协程。但 JDK 21 正式带来的 虚拟线程(Virtual Threads),完全可以看作 Java 版的协程——虽然实现路数跟传统协程不一样,可目标高度一致。
🔹 传统协程是什么
像 Go、Python 的协程,核心就三点:
-
用户态调度,不依赖 OS 线程切换
-
创建成本极低,能扛海量并发
-
有栈/无栈不同流派,但都有挂起、恢复的语义
🔹 Java 走过的路
-
早期:绿色线程(Green Thread)被放弃,全面倒向 OS 线程
-
第三方方案:Quasar(字节码增强真协程)、Kilim、以及 Kotlin 协程在 JVM 上的编译期实现
-
官方大动作:Project Loom → JDK 19 预览 → JDK 21 正式 虚拟线程
🔹 虚拟线程为什么能当“协程”用
它是 JVM 层面的 M:N 调度:一堆虚拟线程映射到少数几条平台线程上。
关键机制:当虚拟线程执行到阻塞操作(I/O、sleep、锁等待)时,JVM 会把它从平台线程上卸载,平台线程马上去执行另一个虚拟线程。阻塞结束再挂回去。
✅ 效果:你可以用最普通的同步、顺序代码,写出能支撑百万并发的程序,完全不用回调、反应式那一套。
❌ 但它不是无栈协程那种需要 suspend 染色的模型,而是有栈的——靠堆上保存调用栈,在阻塞点自动让出,代码零侵入。
🔹 跟 Go 协程的直观对比
⚠️ 注意避坑:虚拟线程怕长时间占用 CPU 不放的场景(比如死循环计算),因为它只在阻塞时才卸载,CPU 密集型会一直霸住平台线程。
🗣️ 如果面试时让我一句话总结
“Java 没有语言层面的 async/await 协程关键字,但 JDK 21 的虚拟线程是 JVM 对协程的官方回答——用线程模型实现协程效果,同步代码直接高并发,生态兼容性拉满。”
说到底,虚拟线程的哲学就是:不换抽象,只换调度,让传统线程编程重新香起来。如果你还想听它内部 Continuation 是怎么挂起栈帧的,或者什么时候会出现 pinning,我可以接着拆。”