平台线程详解
平台线程(Platform Thread)是 Java 最传统的线程实现方式,也是理解虚拟线程的基础。虽然 JDK 21 之后虚拟线程成为主流,但平台线程的原理仍然是 Java 并发编程的核心知识。
平台线程的本质
1:1 映射到 OS 线程
平台线程的本质是 一个 Java Thread 对象映射到一个 OS 线程:
创建过程
当调用 Thread.start() 时,JVM 会通过 JNI 调用 OS 的线程创建接口:
在 JVM 内部,start0() 对应一个 C++ 实现,最终调用 POSIX 线程库(如 pthread_create)或 Windows 线程 API。
线程栈大小配置
默认栈大小
不同平台的默认栈大小:
配置方式
栈大小的选择
栈太大:
- 浪费内存:1000 线程 × 1MB = 1GB 内存
- 增加 GC 压力
栈太小:
- 容易栈溢出:
StackOverflowError - 无法支持深度递归
业务线程池栈大小配置
对于 IO 密集型的业务线程池,可以适当减小栈大小:
线程创建与销毁开销
创建开销
线程创建涉及多个步骤:
销毁开销
线程销毁同样有开销:
- 栈内存释放
- 线程上下文清理
- OS 资源的释放
线程池的必要性
由于线程创建和销毁开销大,线程池成为标准实践:
线程上下文切换
什么是上下文切换
当 CPU 在不同线程之间切换时,需要保存和恢复线程的执行上下文:
上下文切换的成本
上下文切换涉及:
上下文切换的类型
- 自发性切换:线程主动调用
yield()、sleep()或阻塞 - 非自发性切换:时间片用完,被 OS 强制切换
减少上下文切换
线程优先级
优先级设置
优先级的陷阱
重要警告:线程优先级在大多数 OS 上只是「建议」,不是强制:
在 Windows 上,线程优先级的影响相对更明显。但在 Linux 上,调度器主要基于 CFS(Completely Fair Scheduler),优先级影响较小。
最佳实践
- 不要依赖优先级做关键逻辑:优先级只能作为「提示」
- 使用队列顺序:如果需要保证顺序,使用队列而不是优先级
- 避免优先级倒置:低优先级线程持有高优先级线程需要的资源
Daemon 线程
Daemon vs User 线程
区别
注意事项
本章总结
核心要点:
- 平台线程是 1:1 映射:一个 Java Thread 对应一个 OS 线程
- 栈大小约 1MB:可以通过
-Xss配置,但需权衡内存和容量 - 创建销毁开销大:需要线程池复用
- 上下文切换有成本:减少不必要的线程切换
- 优先级只是建议:不要依赖优先级做关键逻辑
- Daemon 线程不保证执行:JVM 退出时不等待 Daemon 线程
理解平台线程是学习虚拟线程的基础。下一节我们将讲解线程的生命周期与状态转换。