八股-JDK
JDK
JDK 5 新特性
泛型(Generics)
详见《泛型》专题笔记
- 引入参数化类型,提供编译期类型安全
- 消除强制类型转换,提升代码复用性
JDK 8 新特性
1. Lambda 表达式
- 核心作用:引入函数式编程,简化匿名内部类语法
- 本质:将函数作为方法参数传递,使代码更简洁、可读性更强
2. Stream 流
- 定义:对集合数据进行高效、声明式处理的 API
- 特点:
- 支持链式操作(Fluent API)
- 支持并行处理(parallelStream)
- 常用于数据过滤、转换、聚合等场景
3. Optional
- 定位:容器类,用于优雅处理可能为 null 的对象
- 价值:
- 强制开发者显式检查空值
- 减少 NullPointerException(NPE)
- 避免冗长的 null 判断代码
JDK 21 新特性
虚拟线程(Virtual Threads)
别名:轻量级线程 / 用户态线程(类似 Go 语言的 Goroutine)
发展历程:JDK 19 引入预览,JDK 21 正式发布
核心概念对比
| 类型 | 定义 | 特点 |
|---|---|---|
| 操作系统线程 | 内核态线程,直接由操作系统管理 | • 数量有限(单进程上限约 6 万个) • 高开销:创建/销毁需系统调用,上下文切换需陷入内核态 |
| 平台线程 | JVM 层面对操作系统线程的 1:1 包装 | • new Thread() 或线程池创建的线程• 严格一对一映射到操作系统线程 • 同样存在高开销问题 |
| 虚拟线程 | JVM 管理的轻量级线程(协程实现) | • 内存占用极小 • 上下文切换无需陷入内核态 • 创建/销毁成本极低(无需池化) • 多个虚拟线程共享一个平台线程(载体线程) |
虚拟线程的工作原理
上下文切换机制:
- 虚拟线程运行时依赖虚拟线程栈和程序计数器
- 切换时,保存当前虚拟线程的上下文(栈、程序计数器等)
- 切换到另一个虚拟线程继续执行
- 关键点:切换过程完全在用户态完成,不涉及内核态切换
1 | ┌─────────────────────────────────────────┐ |
为什么需要虚拟线程?
背景问题:
- 传统模型(如 Tomcat):一个请求对应一个线程
- 单进程线程数有限(约 6 万个),成为并发瓶颈
- 高并发场景下,若请求涉及阻塞 I/O(BIO):
- 线程阻塞等待 I/O 完成
- 大量线程被阻塞,资源耗尽
- CPU 利用率低下(线程都在等待,没有计算)
解决方案:
- 使用虚拟线程处理阻塞操作
- 当虚拟线程遇到 I/O 阻塞时,自动让出载体线程
- 载体线程可调度其他虚拟线程,提高资源利用率
- 单应用可轻松承载百万级并发(而非几万个)
生态支持
目前主流框架已全面支持虚拟线程:
- Tomcat / Jetty:内置虚拟线程支持
- Netty:异步事件驱动 + 虚拟线程
- **SpringBoot 3.2+**:
spring.threads.virtual.enabled=true一键开启
脉络图
1 | JDK 5 ──► 泛型 ───────────────► 编译期类型安全 |