连接池+虚拟线程

1.虚拟线程和异步线程(平台线程)的特点以及区别

  • 平台线程 Java 线程 1:1 绑定操作系统内核线程 ,创建、调度、内存、阻塞全由 OS 内核 管理,JVM 仅做封装。
  • 虚拟线程 JVM 层面自研的轻量逻辑线程 ,OS 完全感知不到;多对一(M:N) 复用少量平台线程作为载体线程,全程由 JVM 在用户态调度。

资源占用:

  • 平台线程 单线程默认占用约 1MB 固定栈内存 ,还有 OS 线程控制块;创建上千个就会明显消耗内存,有系统线程数硬上限。阻塞(IO / 等待)时,整个 OS 线程资源被占用,无法复用
  • 虚拟线程 栈内存JVM 按需分配 ,单线程仅几 KB,开销极小;可轻松创建上万 / 百万级别 ,无数量瓶颈。阻塞时 JVM 自动卸载,载体线程立刻复用去执行其他任务,不浪费 OS 资源。

使用方式:

  • 平台线程 必须手动维护线程池 ,提前设置核心线程、最大线程、队列;线程复用,池满则排队 / 拒绝。日常 new Thread()@Async、Tomcat 工作线程都属于这类。
  • 虚拟线程 无需手动建线程池,任务随用随创建、执行完销毁;JVM 内置少量载体线程,开发者不用配置线程数。

调度与性能

  • 平台线程 OS 内核调度,上下文切换开销大。✅ CPU 密集场景最优 :无 JVM 额外调度逻辑,纯计算性能最高。❌ IO 密集短板:阻塞即浪费线程,并发能力受线程池大小限制。
  • 虚拟线程 JVM 用户态调度,切换开销极低。✅ IO 密集场景最强 :阻塞自动让出载体,并发吞吐量远高于线程池。❌ CPU 密集略弱:持续运算不触发卸载,额外增加 JVM 管理开销,速度稍慢。

兼容性 & 版本

  • 平台线程 全 JDK 版本支持(JDK1.2+),所有旧框架、中间件、ThreadLocal、事务、连接池完全兼容。
  • 虚拟线程 JDK21 正式转正,低版本无法使用;不适配传统 ThreadLocal(推荐 ScopedValue),老业务框架改造有成本;不适合长驻后台任务

适用场景(直接照着选)

👉 优先使用 平台线程 / 线程池

  1. CPU 密集:循环计算、加解密、大数据内存处理、数据解析
  2. 常驻后台任务:MQ 消费、定时任务、长连接监听
  3. 老旧项目、低版本 JDK、强依赖 ThreadLocal/ 线程上下文的业务

👉 优先使用 虚拟线程

  1. IO 密集:数据库查询、Redis、HTTP / 接口调用、文件读写、普通 Web 接口
  2. 高并发短任务,不想维护线程池参数
  3. JDK21 及以上新项目,追求高并发、低资源占用

2.数据库连接池

为什么需要数据库连接池?

答题要点:

  1. 数据库创建 / 销毁连接开销极大(TCP 握手、权限校验、会话初始化),频繁创建严重拖慢性能。
  2. 复用连接,减少开销、提升接口响应速度。
  3. 统一管控连接数量,保护数据库,避免应用无限创建连接压垮 DB。
  4. 统一管理超时、心跳、连接回收,简化开发。

连接池核心思想

提前初始化一批连接放入池中,业务请求从池子里获取连接,使用完毕归还,而非每次新建。

主流连接池对比(高频对比题)

市面主流:HikariCP、Druid、Tomcat JDBC Pool、C3P0 面试常问:SpringBoot 默认为什么选 HikariCP?和 Druid 区别?

  1. HikariCP(SpringBoot 2.x+ 默认)
    • 优点:轻量、速度最快、代码精简、低开销,并发性能顶尖。
    • 特点:追求极致性能,监控、扩展功能偏少。
  2. Druid(阿里)
    • 优点:监控强大、防 SQL 注入、SQL 拦截、慢查询统计、多扩展,运维友好。
    • 缺点:比 Hikari 重一点,纯性能略逊。
  3. 面试标准回答:
    • 纯性能、追求低延迟 → 选 HikariCP
    • 需要全面监控、安全防护、运维审计 → 选 Druid

HikariCP 核心参数

  1. maximum-pool-size 最大连接数
    • 含义:池子允许的最大活跃连接数,DB 侧并发上限。
    • 考点:不是越大越好。MySQL 单库单实例,单应用建议 10~30,超过 50 极易出现锁竞争、上下文切换,性能下降。
  2. minimum-idle 最小空闲连接
    • 含义:池内最少保留的空闲连接。
    • 考点:生产建议 = maximum-pool-size(固定连接池)。理由:关闭动态扩容缩容,避免连接反复创建销毁带来性能抖动。
  3. idle-timeout 空闲连接超时
    • 含义:空闲多久后回收连接。
    • 考点:固定连接池设为 0,禁止回收,连接常驻。
  4. connection-timeout 获取连接超时
    • 含义:从池里拿不到连接时,最大等待时间。
    • 现象:超时抛出 Connection is not available,典型连接池耗尽
  5. max-lifetime 连接最大生命周期
    • 必考坑点:必须小于数据库 wait_timeout(MySQL 默认 8 小时)。
    • 原因:连接被 DB 主动断开,但池还持有旧连接,导致间歇性断连接、SQL 报错

经典面试题:

线上偶尔报数据库连接异常,一会好一会坏,可能是什么原因?答:大概率 max-lifetime 大于 MySQL wait_timeout,连接被 DB 断开,连接池持有失效连接。

  • 连接池如何实现高效取 / 还连接? Hikari 使用FastList + 无锁并发设计,减少锁竞争,这是它速度快的核心原因。
  • 连接池耗尽的整个流程 请求 → 从池获取连接 → 连接已满 → 排队等待 connection-timeout → 超时报错。
  • 连接归还流程 业务 close () 并不是关闭物理连接,而是把连接放回池子。.
  • **Q:说说 HikariCP 核心参数和线上配置?**A:线上采用固定连接池,maximum-pool-size 设 10~25,minimum-idle 和最大值一致,idle-timeout=0 禁止回收空闲连接,max-lifetime 小于 MySQL 超时时间,避免断连。

  • **Q:连接池满了怎么办?**A:先排查慢 SQL、事务过长、循环查库,加缓存;必要时小幅上调连接数,严禁无限加大。

  • **Q:HikariCP 和 Druid 怎么选?**A:追求极致性能选 Hikari;需要 SQL 监控、安全防护、运维审计选 Druid。

  • **Q:为什么不能把 minimum-idle 设很小?**A:会触发连接频繁扩容、销毁,产生性能抖动,生产建议固定连接数。

  • **Q:连接间歇性失效报错原因?**A:连接池内连接生命周期大于数据库空闲超时,连接被 DB 断开,池内残留无效连接

相关推荐
技术小结-李爽1 小时前
【工具】如何认识Maven
java·maven
小碗羊肉1 小时前
【RabbitMQ高级】如何保证消息的可靠性?
java·rabbitmq·java-rabbitmq
xiaoshuaishuai82 小时前
C# 多线程之间对比
java·开发语言·c#
越努力越幸运662 小时前
Java 无需 Office 环境实现 Word 转 HTML
java
用户8176967132352 小时前
Java OOM 排查完整指南:从告警到根因,MAT 堆分析全流程实战
java
要开心吖ZSH3 小时前
AI医疗分诊与健康咨询助手agent开发——(0)项目背景与概要
java·ai·agent·健康医疗·rag
后青春期的诗go3 小时前
泛微OA-E9与第三方系统集成开发企业级实战记录(十五)
java·泛微·集成开发·e9
吃口巧乐兹4 小时前
理解 Agent 中的 Slash Command:从概念到自定义命令实践
java·github
夕除5 小时前
shizhan--10
java·开发语言