java 线程休眠 假死,java多线程-jstack线程阻塞问题排查
线上高并发时,tomcat挂掉了,应用假死等问题,都可以使用jstack查看线程堆栈的问题。
jstack参数解说
首先线程状态如下:
New: 当线程对象创建时存在的状态,此时线程不可能执行;
Runnable:当调用thread.start()后,线程变成为Runnable状态。只要得到CPU,就可以执行;
Running:线程正在执行;
Waiting:执行thread.join()或在锁对象调用obj.wait()等情况就会进该状态,表明线程正处于等待某个资源或条件发生来唤醒自己;
Timed_Waiting:执行Thread.sleep(long)、thread.join(long)或obj.wait(long)等就会进该状态,与Waiting的区别在于Timed_Waiting的等待有时间限制;
Blocked:如果进入同步方法或同步代码块,没有获取到锁,则会进入该状态;
Dead:线程执行完毕,或者抛出了未捕获的异常之后,会进入dead状态,表示该线程结束
其次,对于jstack日志,我们要着重关注如下关键信息
Deadlock:表示有死锁
Waiting on condition:等待某个资源或条件发生来唤醒自己。比如线程正在sleep,网络读写繁忙而等待.
此时线程状态大致为以下几种:
java.lang.Thread.State: WAITING (parking):一直等那个条件发生;
java.lang.Thread.State: TIMED_WAITING (parking或sleeping):定时的,那个条件不到来,也将定时唤醒自己。
Blocked:阻塞
Waiting on monitor entry:在等待获取锁,意味着它在等待进入一个临界区,所以它在”Entry Set“队列中等待,等待获取监视器。
in Object.wait():获取锁后又执行obj.wait()放弃锁,进入等待队列中。
sleeping:休眠的线程,调用了Thread.sleep()。
runnable:正在运行中。
注意: jstack表示的进程当前的状态哦。如果比如看到状态位RUNNABLE的,表示在你执行jstack时,该线程正在运行中。
对于Waiting on monitor entry 和 in Object.wait()的详细描述:Monitor是 Java中用以实现线程之间的互斥与协作的主要手段,它可以看成是对象或者 Class的锁。每一个对象都有,也仅有一个 monitor。从下图中可以看出,每个 Monitor在某个时刻,只能被一个线程拥有,该线程就是 "Running Thread",而其它线程都是 "Waiting Thread",分别在两个队列 " Entry Set"和 "Wait Set"里面等候。
在 "Entry Set"中等待的线程状态是:"Waiting for monitor entry",等待获取锁,在排队呢。
而在 "Wait Set"中等待的线程状态是 "in Object.wait()" 获取了锁,但是执行了wait()操作,线程被挂起,等待被唤醒,同样得重新获取锁。如下图的流转
大量某个状态
如果大量线程在“waiting for monitor entry”:
可能是一个全局锁阻塞住了大量线程。如果短时间内打印的thread dump文件反映,随着时间流逝,waiting for monitor entry 的线程越来越多,没有减少的趋势,可能意味着某些线程在临界区里呆的时间太长了,以至于越来越多新线程迟迟无法进入临界区。
如果大量线程在“waiting on condition”:
可能是获取第三方资源,尤其是第三方网络资源,迟迟获取不到Response,导致大量线程进入等待状态。
所以如果你发现有大量的线程都处在Wait on condition,从线程堆栈看,正等待网络读写,这可能是一个网络瓶颈的征兆,因为网络阻塞导致线程无法执行。
问题状态
Deadlock:表示有死锁
Waiting on condition:等待某个资源或条件发生来唤醒自己。具体需要结合jstacktrace来分析,比如线程正在sleep,网络读写繁忙而等待
Blocked:阻塞
Waiting on monitor entry:在等待获取锁
虽然状态是这么多,但是具体问题还的具体查看,比如等待唤醒的资源,在下一次jstack查看时不存在了,就说明已经获取到锁并执行了。如果存在大量的,且长时间阻塞的那么就说明有很大问题了。
jstack其他参数说明
prio:线程的优先级
tid:线程id
nid:操作系统映射的线程id(16进制)
[0x0000000000000000] :后面末尾的数字,表示线程栈的起始地址。
基础操作
//查找进程号
> jps -lv |grep '应用名称' 或者ps -ef|grep '应用名称'
> jstack 3333 //进程号
top找到堆栈信息
> top //进入top后,shift+H查看线程
找到占用内存较大的线程id
> printf "%x\n" TID 将需要的线程ID转换为16进制格式 (16转10: printf %d\\n 0x5b7f)
> jstack [进程]|grep -A 10 [线程的16进制] //根据jstack找到该线程占用比较大的堆栈信息。
> jstack 13333 |grep -A 10 54f2
其他命令:
输出该进程拥有的线程总数
ps -mp 5841 -o THREAD,tid,time | wc -l
输出占用cpu最大的前10线程
ps -mp 5841 -o THREAD,tid,time | sort -rn | head -10
参考地址
java 线程休眠 假死,java多线程-jstack线程阻塞问题排查相关推荐
- java线程休眠sleep函数_Java多线程中sleep()方法详解及面试题
一. Java线程生命周期(五个阶段) 新建状态就绪状态运行状态阻塞状态死亡状态 如图 二.sleep方法 API中的解释 static voidsleep(long millis) 使当前正在执行的 ...
- java runnable wait_面试官:都说阻塞 I/O 模型将会使线程休眠,为什么 Java 线程状态却是 RUNNABLE?...
摘要: 原创出处 https://studyidea.cn 「公众号:程序通事 」欢迎关注和转载,保留摘要,谢谢! 使用 Java 阻塞 I/O 模型读取数据,将会导致线程阻塞,线程将会进入休眠,从而 ...
- new thread后会阻塞主程序吗_阻塞模型将会使线程休眠,为什么 Java 线程状态却是 RUNNABLE?...
使用 Java 阻塞 I/O 模型读取数据,将会导致线程阻塞,线程将会进入休眠,从而让出 CPU 的执行权,直到数据读取完成.这个期间如果使用 jstack 查看线程状态,却可以发现Java 线程状态 ...
- 既然阻塞 I/O 会使线程休眠,为什么 Java 线程状态却是 RUNNABLE?
使用 Java 阻塞 I/O 模型读取数据,将会导致线程阻塞,线程将会进入休眠,从而让出 CPU 的执行权,直到数据读取完成.这个期间如果使用 jstack 查看线程状态,却可以发现Java 线程状态 ...
- wxpython多线程 假死_wxpython中利用线程防止假死的实现方法
前段时间我编写了一个工业控制的软件,在使用中一直存在一个问题,就是当软件检索设备时,因为这个功能执行的时间比较长,导致GUI界面假死,让用户分辨不清楚软件到底仍在执行,还是真的挂掉了.(虽然我设计了同 ...
- java ee ide 假死_Eclipse编辑jsp、js文件时卡死现象的解决办法汇总
使用Eclipse编辑jsp.js文件时,经常出现卡死现象,在网上百度了N次,经过N次优化调整后,卡死现象逐步好转,具体那个方法起到作用,不太好讲.将所有用过的方法罗列如下: 1.取消验证 windo ...
- qt开启线程界面假死问题解决
一.前言 在 使用qt高速读取传感器数据时,如果想要将数据实时刷新在界面,就需要开启一个线程单独去跑读取数据函数,并反馈给主程序,否则在主程序中读取和刷新界面会很卡很卡,但是在开启多线程,无外接鼠标键 ...
- 2021-11-24 micropython esp32休眠假死 唤醒 rtc nvs btree数据保持
首先本次记录时MICROPYTHON 在ESP32环境下的记录,这里需要声明你使用的micropython 的版本固件不应该太古老,根据我的经验,有些早期固件不支持以下测试,或者不具备相应功能,固件嘛 ...
- wxpython多线程 假死_wxpython多线程防假死与线程间传递消息实例详解
wxpython中启用线程的方法,将GUI和功能的执行分开. 网上关于python多线程防假死与线程传递消息是几年前的,这里由于wxpython和threading模块已经更新最新,因此给出最新修改代 ...
- java如何让线程休眠一分钟_如何使线程在java中休眠特定的时间?
当你的线程被中断击中时,它将进入InterruptedException catch块.然后,您可以检查线程花费了多少时间睡觉,并计算出睡眠时间.最后,不要吞咽异常,恢复中断状态是很好的做法,以便调用 ...
最新文章
- crtmpserver 配置说明_crtmpserver 流媒体服务器 集群 安装配置
- CTFshow 信息收集 web18
- 智能理财在国内国外的发展现状
- javascript数组查重方法总结
- c语言垂直制表的作用,c语言中“\”的用途
- VTK:图片之ImageMagnify
- linux服务器之查看内存使用情况
- vb mysql边记录边统计_vb6 数据库 增加记录
- 无监督︱异常、离群点检测 一分类——OneClassSVM
- KNN(二)--近似最近邻算法ANN
- spark sql读取hive底层_SparkSQL读取Hive数据插入Redis
- OpenStack峰会喊你回家吃饭
- 让openkore 更节省你的CPU和内存
- tcpdump使用详解及数据包分析
- KDA的新宠儿,金贝KD6,更大算力,探索无限可能
- python+twilio实现打电话和发短信功能
- 【POJ3585】Accumulation Degree 二次扫描与换根法
- [Unity] 制作游戏 赛车小游戏
- linux里添加网卡,Linux添加虚拟网卡的多种方法
- php mql获取结果集,mql查询删除更新嵌入求指导php