查看SpringBoot当前线程数的3种有效方法
作者:刘大华
本文介绍了几种监控Spring Boot应用线程状态的方法,包括Spring Boot自带监控、jstack命令、VisualVM和JMC,每种方法都有其适用场景和优缺点,需要的朋友可以参考下
前几天,我在排查一个 SpringBoot 应用响应变慢的问题。日志看不出有什么异常,CPU和内存也还算正常,但用户就是觉得卡。
于是,我在想:是不是某个线程卡住了,或者线程池失控了?现在到底有多少线程在运行?
好在查看线程数并不复杂,不管是临时诊断还是长期监控,都有现成的办法。下面我就分享几种常用的方式。
监控方案
| 监控方式 | 适用场景 | 优点 | 缺点 |
|---|---|---|---|
| Spring Boot Actuator | 生产环境监控 | 集成度高,RESTful接口 | 需要添加依赖和配置 |
| jstack命令 | 紧急问题诊断 | JDK自带,无需配置 | 命令行操作,不够直观 |
| VisualVM | 开发测试环境 | 图形化界面,功能强大 | JDK 9+需要单独安装 |
| JMC | 生产环境深度分析 | 性能分析强大 | 内存占用较高 |
下面我们看看前3种方案是怎么使用的。
一、Spring Boot自带监控(最简单)
步骤1:添加依赖
<!-- 在pom.xml中添加 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
步骤2:修改配置
# 在application.yml中添加
management:
endpoints:
web:
exposure:
include: "metrics,threaddump"
步骤3:启动项目后,查看线程信息
# 查看线程总数 http://127.0.0.1:8080/actuator/metrics/jvm.threads.live
如图

measurement.value 就是当前存活的线程数,配置简单,不用记命令。
安全配置(生产环境)
spring:
security:
user:
name: admin
password: securepassword
management:
server:
port: 9090 # 监控端口与业务端口分离
二、使用jstack命令(最常用)
1. 找到应用ID
# 查看所有Java进程 jps -l # 或者使用ps命令 ps aux | grep java
输出类似:
36756 org.springframework.boot.loader.JarLauncher
如图:

2. 分析线程
jstack 36756
如图:

线程状态说明
- RUNNABLE: 线程正在运行或准备运行
- WAITING: 无限期等待其他线程的特定操作
- TIMED_WAITING: 有限时间等待
- BLOCKED: 等待获取监视器锁
- TERMINATED: 线程已结束
关键线程类型识别
1. JVM系统线程
"Reference Handler" - 引用处理线程 "Finalizer" - 对象终结线程 "Signal Dispatcher" - 信号分发线程 "GC Thread" - 垃圾回收线程(多个)
2. Spring Boot应用线程
"http-nio-8080-exec-*" - Tomcat工作线程 "Catalina-utility-*" - Tomcat工具线程 "HikariPool-*" - 数据库连接池线程
3. 第三方库线程
"lettuce-*" - Redis客户端线程 "boundedElastic-*" - Reactor响应式线程 "mysql-cj-*" - MySQL驱动线程
3. 线程快照
也可以生成线程快照,保存到文件后再慢慢分析
jstack 36756 > thread.txt
快速统计命令:
# 统计总线程数 grep 'java.lang.Thread.State' thread.txt | wc -l # 统计Tomcat线程数 grep '"http-nio' thread.txt | wc -l # 查看线程状态分布 grep 'java.lang.Thread.State' thread.txt | sort | uniq -c
也可以通过自动化监控脚本进行分析
#!/bin/bash
# monitor_threads.sh
APP_NAME="your-spring-boot-app"
LOG_DIR="./thread_dumps"
INTERVAL=60 # 监控间隔(秒)
MAX_DUMPS=10 # 最大转储文件数
mkdir -p $LOG_DIR
while true; do
PID=$(jps -l | grep $APP_NAME | awk '{print $1}')
if [ -z "$PID" ]; then
echo "$(date): 应用未运行"
sleep $INTERVAL
continue
fi
# 生成时间戳
TIMESTAMP=$(date +%Y%m%d_%H%M%S)
# 生成线程转储
jstack $PID > $LOG_DIR/thread_dump_$TIMESTAMP.txt
# 统计线程信息
TOTAL_THREADS=$(grep 'java.lang.Thread.State' $LOG_DIR/thread_dump_$TIMESTAMP.txt | wc -l)
RUNNABLE=$(grep 'java.lang.Thread.State: RUNNABLE' $LOG_DIR/thread_dump_$TIMESTAMP.txt | wc -l)
WAITING=$(grep 'java.lang.Thread.State: WAITING' $LOG_DIR/thread_dump_$TIMESTAMP.txt | wc -l)
BLOCKED=$(grep 'java.lang.Thread.State: BLOCKED' $LOG_DIR/thread_dump_$TIMESTAMP.txt | wc -l)
echo "$(date): 线程统计 - 总数: $TOTAL_THREADS, 运行: $RUNNABLE, 等待: $WAITING, 阻塞: $BLOCKED"
# 清理旧文件
ls -t $LOG_DIR/thread_dump_*.txt | tail -n +$MAX_DUMPS | xargs rm -f
sleep $INTERVAL
done
优点:不用改代码,随时可用
三、使用VisualVM(最直观)
1. 安装步骤
- 访问 visualvm.github.io/
- 下载对应版本
- 解压后运行
bin/visualvm
2. 使用方法
- 启动VisualVM
# Windows visualvm.exe # Linux/macOS ./visualvm
- 在左边找到你的应用
- 点击应用名称就能看到基础信息页了
如图

Monitor 监控页

界面说明
- CPU使用率:查看方法执行时间
- 堆内存使用:监控内存泄漏
- Metaspace:JDK 17中的元数据空间
- 类加载数量
- 线程数:实时查看线程创建和销毁
Threads 线程标签页(最重要)

界面说明
- 实时查看所有线程状态
- 颜色标识:
- 绿色:运行中 (RUNNABLE)
- 黄色:等待 (WAITING, TIMED_WAITING)
- 红色:阻塞 (BLOCKED)
- 可以生成线程转储(相当于jstack)
这里可以查看线程的详细信息

详细信息内容看到的就和我们上面执行的结果是一样的,需要的话可以复制下来保存到本地

3. 远程监控配置
应用端配置
启动Spring Boot时添加JMX参数:
java -Dcom.sun.management.jmxremote \
-Dcom.sun.management.jmxremote.port=9090 \
-Dcom.sun.management.jmxremote.ssl=false \
-Dcom.sun.management.jmxremote.authenticate=false \
-Dcom.sun.management.jmxremote.local.only=false \
-Djava.rmi.server.hostname=你的服务器IP \
-jar your-app.jar
VisualVM连接配置
- 右键"远程" → "添加远程主机"
- 输入主机名或IP地址
- 右键远程主机 → "添加JMX连接"
- 输入端口号(9090)
优点:图形界面,一目了然
四、问题排查案例
案例1:应用变慢
# 1. 生成线程快照 jstack 36756 > slow.txt # 2. 查看有没有BLOCKED线程 grep "BLOCKED" slow.txt # 3. 查看Tomcat线程在干什么 grep -A 5 "http-nio" slow.txt
案例2:内存占用高
# 查看线程总数是否异常 grep 'java.lang.Thread.State' thread.txt | wc -l
正常:30-100个线程 异常:超过500个线程
案例3:应用无响应
# 强制生成线程快照 jstack -F 36756 > stuck.txt # 查找死锁 grep -i "deadlock" stuck.txt
总结
如果你在开发或测试阶段,想快速直观地了解线程状态,VisualVM 是最友好的选择。
如果你正在线上排查问题,又不方便改代码或重启服务,jstack 这类 JDK 自带命令就是你的急救包,轻量、不需要其它依赖。
而如果你已经部署了监控体系,那么 SpringBoot Actuator 不仅能告诉你线程数量,还能集成到 Prometheus、Grafana 等监控平台,实现自动化告警。
以上就是查看SpringBoot当前线程数的3种有效方法的详细内容,更多关于SpringBoot当前线程数查看的资料请关注脚本之家其它相关文章!
