jstack 线程状态详解

Java 专栏收录该内容
6 篇文章 0 订阅

jatsck 用法

#jstack -h
Usage:
    jstack [-l] <pid>
        (to connect to running process)
    jstack -F [-m] [-l] <pid>
        (to connect to a hung process)
    jstack [-m] [-l] <executable> <core>
        (to connect to a core file)
    jstack [-m] [-l] [server_id@]<remote server IP or hostname>
        (to connect to a remote debug server)

Options:
    -F  to force a thread dump. Use when jstack <pid> does not respond (process is hung)
    -m  to print both java and native frames (mixed mode)
    -l  long listing. Prints additional information about locks
    -h or -help to print this help message

在这里插入图片描述

线程状态

状态含义触发方法线程动作(线程状态产生的原因)备注
NEWThread state for a thread which has not yet started.不会出现在Dump中
RUNNABLEThread state for a runnable thread. A thread in the runnable state is executing in the Java virtual machine but it may be waiting for other resources from the operating system such as processor.runnable
BLOCKEDThread state for a thread blocked waiting for a monitor lock. A thread in the blocked state is waiting for a monitor lock to enter a synchronized block/method or reenter a synchronized block/method after calling Object.wait.waiting for monitor entry
WAITINGThread state for a waiting thread.Object.wait with no timeout => WAITING (on object monitor)in Object.wait()A thread that has called Object.wait() on an object is waiting for another thread to call Object.notify() or Object.notifyAll() on that object.
Thread.join with no timeout=> WAITING (on object monitor)in Object.wait()A thread that has called Thread.join() is waiting for a specified thread to terminate.
LockSupport.park=> WAITING(parking)waiting on condition
TIMED_WAITINGThread state for a waiting thread with a specified waiting time.Thread.sleep=> TIMED_WAITING (sleeping)waiting on condition
Object.wait with timeout=> TIMED_WAITING (on object monitor)in Object.wait()
Thread.join with timeout=> TIMED_WAITING (on object monitor)in Object.wait()
LockSupport.parkNanos=> TIMED_WAITING (parking)waiting on condition
LockSupport.parkUntil=> TIMED_WAITING (parking)waiting on condition
TERMINATEDThread state for a terminated thread. The thread has completed execution.不会出现在Dump中

一图以庇之

在这里插入图片描述

系统线程状态 (Native Thread Status)

系统线程有如下状态:

  • deadlock
    死锁线程,一般指多个线程调用期间进入了相互资源占用,导致一直等待无法释放的情况。

  • runnable
    一般指该线程正在执行状态中,该线程占用了资源,正在处理某个操作,如通过SQL语句查询数据库、对某个文件进行写入等。

  • blocked
    线程正处于阻塞状态,指当前线程执行过程中,所需要的资源长时间等待却一直未能获取到,被容器的线程管理器标识为阻塞状态,可以理解为等待资源超时的线程。

  • waiting on condition
    线程正处于等待资源或等待某个条件的发生,具体的原因需要结合下面堆栈信息进行分析。

    1. 如果堆栈信息明确是应用代码,则证明该线程正在等待资源,一般是大量读取某种资源且该资源采用了资源锁的情况下,线程进入等待状态,等待资源的读取,或者正在等待其他线程的执行等。
    2. 如果发现有大量的线程都正处于这种状态,并且堆栈信息中得知正等待网络读写,这是因为网络阻塞导致线程无法执行,很有可能是一个网络瓶颈的征兆:
      • 网络非常繁忙,几乎消耗了所有的带宽,仍然有大量数据等待网络读写;
      • 网络可能是空闲的,但由于路由或防火墙等原因,导致包无法正常到达;

    所以一定要结合系统的一些性能观察工具进行综合分析,比如netstat统计单位时间的发送包的数量,看是否很明显超过了所在网络带宽的限制;观察CPU的利用率,看系统态的CPU时间是否明显大于用户态的CPU时间。这些都指向由于网络带宽所限导致的网络瓶颈。

    1. 还有一种常见的情况是该线程在 sleep,等待 sleep 的时间到了,将被唤醒。
  • waiting for monitor entry 或 in Object.wait()

Moniter 是Java中用以实现线程之间的互斥与协作的主要手段,它可以看成是对象或者class的锁,每个对象都有,也仅有一个 Monitor。

在这里插入图片描述
从上图可以看出,每个Monitor在某个时刻只能被一个线程拥有,该线程就是 “Active Thread”,而其他线程都是 “Waiting Thread”,分别在两个队列 "Entry Set"和"Waint Set"里面等待。其中在 “Entry Set” 中等待的线程状态是 waiting for monitor entry,在 “Wait Set” 中等待的线程状态是 in Object.wait()。

(1)"Entry Set"里面的线程。
我们称被 synchronized 保护起来的代码段为临界区,对应的代码如下:

synchronized(obj) { }COPY

当一个线程申请进入临界区时,它就进入了 “Entry Set” 队列中,这时候有两种可能性:

该Monitor不被其他线程拥有,"Entry Set"里面也没有其他等待的线程。本线程即成为相应类或者对象的Monitor的Owner,执行临界区里面的代码;此时在Thread Dump中显示线程处于 “Runnable” 状态。

该Monitor被其他线程拥有,本线程在 “Entry Set” 队列中等待。此时在Thread Dump中显示线程处于 “waiting for monity entry” 状态。

临界区的设置是为了保证其内部的代码执行的原子性和完整性,但因为临界区在任何时间只允许线程串行通过,这和我们使用多线程的初衷是相反的。如果在多线程程序中大量使用synchronized,或者不适当的使用它,会造成大量线程在临界区的入口等待,造成系统的性能大幅下降。如果在Thread Dump中发现这个情况,应该审视源码并对其进行改进。

(2)"Wait Set"里面的线程
当线程获得了Monitor,进入了临界区之后,如果发现线程继续运行的条件没有满足,它则调用对象(通常是被synchronized的对象)的wait()方法,放弃Monitor,进入 "Wait Set"队列。只有当别的线程在该对象上调用了 notify()或者notifyAll()方法,"Wait Set"队列中的线程才得到机会去竞争,但是只有一个线程获得对象的Monitor,恢复到运行态。"Wait Set"中的线程在Thread Dump中显示的状态为 in Object.wait()。通常来说,

通常来说,当CPU很忙的时候关注 Runnable 状态的线程,反之则关注 waiting for monitor entry 状态的线程。

  • 1
    点赞
  • 0
    评论
  • 2
    收藏
  • 一键三连
    一键三连
  • 扫一扫,分享海报

相关推荐
©️2020 CSDN 皮肤主题: Age of Ai 设计师:meimeiellie 返回首页
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值