Java 如何看线程堆栈

你或许遇到过这种情况:打开一个常用的APP,有时候会突然变卡、反应慢,甚至提示“无响应”——除了手机本身的内存问题,还可能是后台运行的程序里,某个“小任务”卡在了半路,把资源占满了。放在电脑的Java程序里,这种“小任务”就是线程,而要找出哪个线程“偷懒”或“卡壳”,就得用到“线程堆栈”。

什么是Java线程堆栈?

简单说,线程堆栈就是Java线程在运行时的“工作日记本”。每个线程运行时,都会在这个“本子”上记下自己正在做的事:比如调用了哪个方法、处理了什么数据、走到了哪一步。如果线程卡住了,“日记本”里的记录就会停在那个时间点,我们顺着记录就能找到问题所在。

Java 如何看线程堆栈

举个生活化的例子:你周末在家收拾房间,同时做三件事——擦桌子、洗衣服、整理衣柜。这三件事就是三个线程。如果洗衣机突然卡住不转了,你要找问题,就得看洗衣机的“运行记录”(相当于线程堆栈),是卡了进水阀,还是滚筒被衣服缠住了。Java的线程堆栈,就是给每个运行中的线程做的类似“运行记录”。

怎么查看Java线程堆栈?

查看线程堆栈不用复杂的编程工具,普通开发者甚至运维人员,用现成的命令就能搞定,分两步走:

**找到Java程序的进程号**

每个运行的程序在电脑里都有一个唯一的“身份证号”,也就是进程号。要找Java程序的进程,Windows系统打开命令提示符,输入tasklist | findstr "java";Mac或Linux系统打开终端,输入ps -ef | grep java。运行后会跳出一串信息,找到对应你要查的Java程序,那串数字就是进程号(记为PID)。

比如你电脑里同时运行了游戏、浏览器和Java写的订单系统,输入命令后跳出的信息里,订单系统对应的PID是1234,这就是你要找的目标。

**导出线程堆栈信息**

拿到PID后,就可以导出“运行记录”了。Windows用命令jstack 1234,Mac/Linux用jstack 1234(注意jstack是Java自带的工具,只要装了JDK就能用)。运行后会弹出一堆文字,这就是所有线程的“日记本”。

怎么读懂线程堆栈里的信息?

导出的信息里会有很多线程,我们要重点看两种状态的线程:

  • RUNNABLE(可运行状态):这种线程是正常工作的,就像你正常擦桌子,正在做该做的事,没问题。
  • BLOCKED(阻塞状态):这种线程卡住了,就像你擦桌子时,发现抹布被另一个人拿走了,只能等着。如果很多线程都卡在同一个“拿抹布”的步骤,说明那个“抹布”(相当于共享资源)被某个线程占住不放,导致大家都卡住。

举个例子:如果订单系统的线程堆栈里,有10个线程都显示“等待锁”,而且都卡在“更新订单库存”的步骤,那很可能是某个线程在处理订单时,一直占着库存的“锁”没释放,其他线程只能等着,系统就会变卡。

看完堆栈后要注意什么?

导出的线程堆栈只是“记录”,不是“解决方案”。比如你找到某个线程卡住了,不能直接删除它,而是要顺着“日记本”的记录,看它在调用哪个方法,是不是逻辑里有死循环、或者没释放的资源。

另外,查看线程堆栈的时机很重要:要在系统卡的时候导出,就像洗衣机卡住时拍记录,要是没卡住时拍,可能看不出问题。最好的做法是连续导出几次(比如间隔1秒导出3次),如果同一个线程每次都卡在同一个位置,那这个线程就是真的有问题。

掌握了查看和读懂Java线程堆栈的方法,就像给程序做了一次“体检”,能快速找到卡顿、无响应的原因,不用再盲目重启程序,节省不少时间。

上一篇 C / C++ 编程语言核心特性与实际应用场景的知识科普解读