平台线程 vs 虚拟线程 在 Java

发布: (2026年2月4日 GMT+8 02:07)
5 min read
原文: Dev.to

Source: Dev.to

平台线程

在 Java 中,经典的线程模型称为 平台线程。这些是直接由操作系统支持的传统线程。

Thread thread = new Thread(() -> {
    doWork();
});
thread.start(); // Starts a new platform thread

起初感觉很强大——你得到真正的并行工作和实际的多任务。然而,当你:

  • 创建太多线程 → 应用程序变慢。
  • 处理成千上万的请求 → 线程池耗尽。
  • 执行阻塞 I/O → 线程在等待外部操作时处于空闲状态。

为什么? 因为平台线程直接映射到 OS 线程:

  • 一个 Java 线程 = 一个 OS 线程。
  • OS 线程代价高(大栈、调度开销)。

于是,开发者会采用:

  • 固定大小的线程池。
  • 异步 API。
  • 响应式编程。
  • 复杂的执行模型。

这些变通方案并非出于需求,而是平台线程可扩展性限制所致。

核心问题

在 I/O 操作期间,线程:

  • 不执行计算。
  • 不使用 CPU。
  • 仅等待外部操作完成。

但它占用了稀缺的 OS 资源。这正是 虚拟线程 发挥作用的地方。

虚拟线程 — 轻量且可扩展

虚拟线程是由 JVM 管理的轻量线程,能够在不产生 OS 线程开销的情况下并发数百万任务。

Thread thread = Thread.startVirtualThread(() -> {
    doWork();
});
  • 与平台线程相同的编程模型和阻塞风格。
  • 由 JVM 创建和调度,而不是永久绑定到 OS 线程。
  • 与平台线程相比极其廉价。

实际发生的事情

  • 运行时:虚拟线程被挂载到一个 载体(平台)线程上。
  • 阻塞时:虚拟线程被停放,释放载体线程。
  • 解除阻塞时:它在任意可用的载体线程上恢复执行。

因此,仅阻塞的是虚拟线程本身,而不是底层的 OS 线程。这消除了平台线程的可扩展性瓶颈:

  • 阻塞 I/O 不再浪费 OS 线程。
  • 线程池不再是硬性限制。
  • 简单的阻塞代码可以扩展到大规模并发。

虚拟线程并没有消除阻塞,它消除了阻塞的成本

它们的区别

关键区别在于每种线程处理阻塞的方式:

方面平台线程虚拟线程
映射与 OS 线程一对一多个虚拟线程共享载体线程
阻塞影响阻塞一个 OS 线程只阻塞虚拟线程本身
创建成本高(栈、调度)低(JVM 管理)
可扩展性受 OS 资源限制可处理数百万并发任务

何时使用哪种线程更合适

何时使用虚拟线程

  • 工作负载以 I/O 为主(例如处理大量并发请求)。
  • 需要等待数据库、外部 API 或文件系统。
  • 构建 Web 服务器、API 或微服务。
  • 想要使用简单的阻塞代码且仍能实现可扩展性。

何时使用平台线程

  • 工作负载以 CPU 为主。
  • 需要与操作系统进行紧密交互。
  • 涉及线程绑定、原生调用或其他低层操作。

实际指南

等待时使用虚拟线程,计算时使用平台线程。

这条规则覆盖了大多数真实场景的决策。

虚拟线程并不会让 Java 更快;它让你能够编写简单的阻塞代码,而不必担心线程池的限制。

Back to Blog

相关文章

阅读更多 »

Java 虚拟线程 — 快速指南

Java 虚拟线程 — 快速指南 Java 21+ · Spring Boot 3.2+ · Project Loom 一个简明、面向生产的 Java 虚拟线程指南 — 它们是什么,如何…

JDK

什么是 JDK?JDK 是一个完整的软件包,用于开发 Java 应用程序。它包含用于编写、编译、调试和运行 Java 程序的工具。When is J...

运算符

什么是 Java 中的运算符?运算符是用于对变量和数值执行操作的符号。Java 中运算符的类型——算术运算符——赋值运算符……