温馨提示×

centos java日志线程死锁怎么找

小樊
43
2026-09-12 00:29:13
栏目: 编程语言

在 CentOS 上排查 Java 日志中的线程死锁,通常可以按下面步骤来做。


一、确认是不是死锁

常见现象:

  • 应用“卡死”,CPU 不高
  • 某些请求一直不返回
  • 日志中长时间没有业务日志
  • jstack 提示 Found one Java-level deadlock

二、使用 jstack 找死锁(最常用)

1. 找到 Java 进程 PID

ps -ef | grep java
# 或
jps -l

2. 导出线程栈

jstack -l <pid> > thread_dump.log

3. 直接看死锁信息

grep -A 50 "deadlock" thread_dump.log

或搜索:

Found one Java-level deadlock

4. 死锁示例说明

"Thread-1":
  waiting to lock monitor 0x00007f... (object 0x00000000)
  which is held by "Thread-2"

"Thread-2":
  waiting to lock monitor 0x00007f... (object 0x00000000)
  which is held by "Thread-1"

→ 这说明两个线程互相等待对方持有的锁。


三、结合日志定位代码

1. 从 jstack 中看线程名

"http-nio-8080-exec-3"

2. 看线程栈中的业务代码

at com.xxx.service.OrderService.lockInventory(OrderService.java:120)

→ 去对应代码看:

  • synchronized
  • ReentrantLock
  • 数据库锁
  • 多个锁的获取顺序

四、常见问题点(死锁高发)

1. 锁顺序不一致

// 线程A
lock(a); lock(b);

// 线程B
lock(b); lock(a);

✅ 解决:统一加锁顺序


2. 在锁内调用外部方法

synchronized(lock){
    remoteCall(); // 可能阻塞
}

3. 使用 ReentrantLock 忘记 unlock

lock.lock();
try {
   ...
} finally {
   lock.unlock(); // 必须有
}

4. 数据库连接死锁

  • 事务未提交
  • 多个事务交叉更新同一批数据

可配合:

SHOW PROCESSLIST;

五、自动化辅助工具

1. 检测死锁(代码中)

ThreadMXBean mx = ManagementFactory.getThreadMXBean();
long[] ids = mx.findDeadlockedThreads();

2. 使用 Arthas(强烈推荐)

curl -O https://arthas.aliyun.com/arthas-boot.jar
java -jar arthas-boot.jar
thread -b   # 直接显示死锁线程

六、总结排查流程

应用卡死
  ↓
jps 找 PID
  ↓
jstack -l PID
  ↓
找 deadlock
  ↓
看线程栈 → 定位代码
  ↓
修复锁顺序 / 释放锁 / 缩小锁范围

如果你愿意,可以把 jstack 日志片段相关 Java 代码 发出来,我可以直接帮你分析死锁原因。

0