20210610 线程数不断飙升问题定位

Posted 陈如水

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了20210610 线程数不断飙升问题定位相关的知识,希望对你有一定的参考价值。

分析线程快照的维度

有多少线程在RUNNABLE,BLOCKED,WAITING和TIMED_WAITING状态?哪一个线程被阻塞了?谁在阻塞别人?哪一个对象被锁了?关注的是运行状态/阻塞状态。

1)RUNNABLE 线程运行中或I/O等待

2)BLOCKED 线程在等待monitor锁(synchronized关键字)

3)TIMED_WAITING 线程在等待唤醒,但设置了时限,超过时限自动唤醒。

4)WAITING 线程在无限等待唤醒;

 

WAITING

在对象上的线程调用了Object.wait()会进入WAITING状态,直到另一个线程在这个对象上调用了Object.notify()或Object.notifyAll()方法才能恢复。一个调用了Thread.join()的线程会进入WAITING状态直到一个特定的线程来结束。

 

TIMED_WAITING

进入到Timed Waiting(计时等待)状态的两种方法

1)使用sleep()方法,线程睡醒之后进入到Runnable/Blocked状态;

2)使用wait()方法,wait()如果在毫秒值结束之后还没有被notify()唤醒,就会自动醒来,线程进入到Runnable/Blocked状态;

自动唤醒后,如果能够获得Cpu的时间片,就可以继续执行。和Thread.sleep( ) 方法一样。

 

Sleep 时的线程状态

TIMED_WAITING 与 WAITING 间的联系还是很紧密的,主要差异在时限(timeout)参数上。

sleep 时的线程状态,进入 TIMED_WAITING 状态的另一种常见情形是调用的 sleep 方法,单独的线程也可以调用。

sleep 方法不会释放锁。javadoc中的确切说法是:The thread does not lose ownership of any monitors.(线程不会失去任何 monitor 的所有权)sleep会持有锁,wait不会。

 

BLOCKED

BLOCKED 同样可以视作是一种特殊的,隐式的 wait/nofity 机制。等待的条件就是“有锁还是没锁”。

BLOCKED 状态是与 Java 语言级别的 synchronized 机制相关的。

WAITING 状态属于主动地显式地申请的阻塞,BLOCKED 则属于被动的阻塞。

 

1,现象

通过监控发现,程序中线程数不断飙升。

top -H -p pid 也可以查询当前进程中的线程数量。

2,分析

通过jstack -l pid > thread.log 打印线程快照,并进行分析。

在想一个问题:为什么会创建那么多线程? 都是谁创建的? 

用线程分析工具分析一下线程的状况:

把线程快照在线进行分析发现:大量线程的创建都和消息队列有关系。

3,解决

在创建消息队列客户端的时候,如果不设置消费消息线程数和拉取消息线程数,wmb本身会不断去创建新的线程去处理,没有复用原来的线程。

线程分类:大部分线程都在做什么事情?

以上是关于20210610 线程数不断飙升问题定位的主要内容,如果未能解决你的问题,请参考以下文章

20210610 线程数不断飙升问题定位

20210610 线程数不断飙升问题定位

一次排查Jvm线程飙升问题的经历

系统CPU飙升 三步快速定位问题

关于CPU飙升时的排查过程

[原]调试实战——程序CPU占用率飙升,你知道如何快速定位吗?