查看SpringBoot当前线程数的3种有效方法

 更新时间:2025年12月30日 09:26:59   作者:刘大华  
本文介绍了几种监控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. 安装步骤

  1. 访问 visualvm.github.io/
  2. 下载对应版本
  3. 解压后运行bin/visualvm

2. 使用方法

  1. 启动VisualVM
# Windows
visualvm.exe

# Linux/macOS
./visualvm
  1. 在左边找到你的应用
  2. 点击应用名称就能看到基础信息页了

如图

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连接配置

  1. 右键"远程" → "添加远程主机"
  2. 输入主机名或IP地址
  3. 右键远程主机 → "添加JMX连接"
  4. 输入端口号(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 不仅能告诉你线程数量,还能集成到 PrometheusGrafana 等监控平台,实现自动化告警。

以上就是查看SpringBoot当前线程数的3种有效方法的详细内容,更多关于SpringBoot当前线程数查看的资料请关注脚本之家其它相关文章!

相关文章

  • SpringBoot集成kafka全面实战记录

    SpringBoot集成kafka全面实战记录

    在实际开发中,我们可能有这样的需求,应用A从TopicA获取到消息,经过处理后转发到TopicB,再由应用B监听处理消息,即一个应用处理完成后将该消息转发至其他应用,完成消息的转发,这篇文章主要介绍了SpringBoot集成kafka全面实战,需要的朋友可以参考下
    2021-11-11
  • 聊聊BeanUtils.copyProperties和clone()方法的区别

    聊聊BeanUtils.copyProperties和clone()方法的区别

    这篇文章主要介绍了聊聊BeanUtils.copyProperties和clone()方法的区别,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-09-09
  • JDK8 HashMap红黑树退化为链表的机制方式

    JDK8 HashMap红黑树退化为链表的机制方式

    这篇文章主要介绍了JDK8 HashMap红黑树退化为链表的机制方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2025-05-05
  • SpringBoot整合Hashids实现数据ID加密隐藏的全过程

    SpringBoot整合Hashids实现数据ID加密隐藏的全过程

    这篇文章主要为大家详细介绍了SpringBoot整合Hashids实现数据ID加密隐藏的全过程,文中的示例代码讲解详细,对大家的学习或工作有一定的帮助,感兴趣的小伙伴可以跟随小编一起学习一下
    2024-01-01
  • BeanUtils.copyProperties()属性名相同但是类型不同问题

    BeanUtils.copyProperties()属性名相同但是类型不同问题

    这篇文章主要介绍了BeanUtils.copyProperties()属性名相同但是类型不同问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2024-09-09
  • 基于springboot+jwt实现刷新token过程解析

    基于springboot+jwt实现刷新token过程解析

    这篇文章主要介绍了基于springboot+jwt实现刷新token过程解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-03-03
  • SpringApplicationRunListener监听器源码详解

    SpringApplicationRunListener监听器源码详解

    这篇文章主要介绍了SpringApplicationRunListener监听器源码详解,springboot提供了两个类SpringApplicationRunListeners、SpringApplicationRunListener(EventPublishingRunListener),spring框架还提供了一个ApplicationListener接口,需要的朋友可以参考下
    2023-11-11
  • Java工作环境的配置与Eclipse的安装过程

    Java工作环境的配置与Eclipse的安装过程

    这篇文章主要介绍了Java工作环境的配置与Eclipse的安装过程,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2021-02-02
  • Java如何实现双向链表功能

    Java如何实现双向链表功能

    双向链表也叫双链表,是链表的一种,它的每个数据结点中都有两个指针,分别指向直接后继和直接前驱。所以,从双向链表中的任意一个结点开始,都可以很方便地访问它的前驱结点和后继结点。一般我们都构造双向循环链表
    2021-11-11
  • JAVA中使用openoffice将Excel转PDF再转图片功能的实现代码

    JAVA中使用openoffice将Excel转PDF再转图片功能的实现代码

    这篇文章主要介绍了JAVA中使用openoffice将Excel转PDF再转图片功能实现,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2021-12-12

最新评论