0

0

Java中如何检测死锁并主动抛出异常监控_基于ThreadMXBean的实战

P粉602998670

P粉602998670

发布时间:2026-02-21 15:01:26

|

904人浏览过

|

来源于php中文网

原创

threadmxbean.finddeadlockedthreads() 返回 null 是正常现象,因仅检测 jvm 内置锁的循环阻塞态;需周期轮询、结合超时与阈值判断,并区分 synchronized 与 reentrantlock 等显式锁的监控差异。

java中如何检测死锁并主动抛出异常监控_基于threadmxbean的实战

ThreadMXBean.findDeadlockedThreads() 返回 null 怎么办

它不是每次都能查到死锁,只在 JVM 检测到「互相持有对方等待的锁」且处于阻塞态时才返回非空数组。如果线程刚卡住、还没完成锁状态同步,或者用的是 java.util.concurrent 里的非内置锁(比如 ReentrantLocktryLock() 配合自定义等待逻辑),findDeadlockedThreads() 就会返回 null

实操建议:

立即学习Java免费学习笔记(深入)”;

  • 别只依赖单次调用,得周期性轮询(比如每 5 秒一次),配合时间窗口判断:连续 3 次都返回非空,才认为是真实死锁
  • 注意 JVM 参数影响:-XX:+UseParallelGC-XX:+UseZGC 下,锁状态快照可能延迟更高,ZGC 尤其明显
  • 必须开启监控权限:运行时需带 -Dcom.sun.management.jmxremote,且程序要有 ManagementFactory.getThreadMXBean() 的访问权限(某些容器环境默认禁用)

检测到死锁后怎么主动抛异常而不是等线程卡死

ThreadMXBean 只负责“发现”,不负责“干预”。想让死锁现场立刻暴露,得自己写中断逻辑——但不能直接调 thread.stop()(已废弃且危险),也不能简单 interrupt()(对 synchronized 阻塞无效)。

实操建议:

立即学习Java免费学习笔记(深入)”;

  • 对每个死锁线程,检查它的栈帧:若最上层是 Object.wait()LockSupport.park()synchronized 进入点,说明卡在锁上,此时可记录日志并触发告警,但不要强行 resume
  • 更稳妥的做法是:在检测到死锁后,向业务层抛出自定义异常(如 DeadlockDetectedException),由上层统一做 graceful shutdown 或 fallback 处理
  • 示例代码片段:
    long[] ids = threadBean.findDeadlockedThreads();
    if (ids != null && ids.length > 0) {
        throw new DeadlockDetectedException("Deadlock detected on threads: " + Arrays.toString(ids));
    }

ReentrantLock 死锁 detect 不到?原因和绕过方案

ThreadMXBean.findDeadlockedThreads() 只识别 JVM 内置锁(synchronizedObject.wait() 相关),对 ReentrantLockStampedLock 等显式锁完全无感——它们的等待队列在用户态维护,JVM 线程状态仍是 RUNNABLE,不会被标记为 BLOCKED

Dang.ai
Dang.ai

Dang.ai是一个AI工具目录集,已收集超过5000+ AI工具

下载

实操建议:

立即学习Java免费学习笔记(深入)”;

  • ReentrantLock.getHoldCount()getQueueLength() 做辅助判断:当某个锁的持有数 > 0 且等待数持续增长(比如 10 秒内从 0 到 5+),大概率出现逻辑死锁
  • 强制要求所有 ReentrantLock 使用带超时的 tryLock(long, TimeUnit),并在超时后抛异常,避免无限等待
  • 如果必须监控显式锁,改用 java.util.concurrent.locks.LockSupport 配合 Thread.currentThread().getStackTrace() 做采样分析,但开销大,仅限诊断期开启

生产环境高频检测导致 GC 压力大怎么办

每秒调一次 findDeadlockedThreads() 看似轻量,但底层会触发全堆锁状态快照,尤其在线程数 > 500 时,容易引发 ParNew GC 频繁或 ZGC 中的 Pause For GC 时间上升。

实操建议:

立即学习Java免费学习笔记(深入)”;

  • 把检测频率从“实时”降为“懒检测”:只在收到特定 JMX 请求、或 HTTP 健康检查端点被调用时才执行一次
  • 加一层缓存:结果存 ConcurrentHashMap<string long></string>,键为线程 ID 列表哈希,30 秒内相同结果不重复上报
  • 避免在日志里打印完整线程栈——threadBean.getThreadInfo(id, 10) 的 10 层栈深度在高并发下极易打爆日志磁盘,改成只记 thread.getName()thread.getState()

真正难的不是检测,是区分「瞬时锁竞争」和「真死锁」;很多人加了监控却没设阈值、没配衰减策略,结果告警刷屏后直接关掉功能。留个心眼:死锁通常不会单独发生,它背后大概率连着资源泄漏或线程池配置错误。

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
string转int
string转int

在编程中,我们经常会遇到需要将字符串(str)转换为整数(int)的情况。这可能是因为我们需要对字符串进行数值计算,或者需要将用户输入的字符串转换为整数进行处理。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

810

2023.08.02

c语言中null和NULL的区别
c语言中null和NULL的区别

c语言中null和NULL的区别是:null是C语言中的一个宏定义,通常用来表示一个空指针,可以用于初始化指针变量,或者在条件语句中判断指针是否为空;NULL是C语言中的一个预定义常量,通常用来表示一个空值,用于表示一个空的指针、空的指针数组或者空的结构体指针。

246

2023.09.22

java中null的用法
java中null的用法

在Java中,null表示一个引用类型的变量不指向任何对象。可以将null赋值给任何引用类型的变量,包括类、接口、数组、字符串等。想了解更多null的相关内容,可以阅读本专题下面的文章。

826

2024.03.01

堆和栈的区别
堆和栈的区别

堆和栈的区别:1、内存分配方式不同;2、大小不同;3、数据访问方式不同;4、数据的生命周期。本专题为大家提供堆和栈的区别的相关的文章、下载、课程内容,供大家免费下载体验。

421

2023.07.18

堆和栈区别
堆和栈区别

堆(Heap)和栈(Stack)是计算机中两种常见的内存分配机制。它们在内存管理的方式、分配方式以及使用场景上有很大的区别。本文将详细介绍堆和栈的特点、区别以及各自的使用场景。php中文网给大家带来了相关的教程以及文章欢迎大家前来学习阅读。

594

2023.08.10

堆和栈的区别
堆和栈的区别

堆和栈的区别:1、内存分配方式不同;2、大小不同;3、数据访问方式不同;4、数据的生命周期。本专题为大家提供堆和栈的区别的相关的文章、下载、课程内容,供大家免费下载体验。

421

2023.07.18

堆和栈区别
堆和栈区别

堆(Heap)和栈(Stack)是计算机中两种常见的内存分配机制。它们在内存管理的方式、分配方式以及使用场景上有很大的区别。本文将详细介绍堆和栈的特点、区别以及各自的使用场景。php中文网给大家带来了相关的教程以及文章欢迎大家前来学习阅读。

594

2023.08.10

线程和进程的区别
线程和进程的区别

线程和进程的区别:线程是进程的一部分,用于实现并发和并行操作,而线程共享进程的资源,通信更方便快捷,切换开销较小。本专题为大家提供线程和进程区别相关的各种文章、以及下载和课程。

695

2023.08.10

pixiv网页版官网登录与阅读指南_pixiv官网直达入口与在线访问方法
pixiv网页版官网登录与阅读指南_pixiv官网直达入口与在线访问方法

本专题系统整理pixiv网页版官网入口及登录访问方式,涵盖官网登录页面直达路径、在线阅读入口及快速进入方法说明,帮助用户高效找到pixiv官方网站,实现便捷、安全的网页端浏览与账号登录体验。

796

2026.02.13

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Kotlin 教程
Kotlin 教程

共23课时 | 3.8万人学习

C# 教程
C# 教程

共94课时 | 9.9万人学习

Java 教程
Java 教程

共578课时 | 69.7万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号