java高*之jstack命令使用

时间:2022-10-30 17:19:12

java高*之jstack命令使用

此命令用来分析线程栈信息。为了了解此命令,写一段程序如下:

package com.test;

import java.io.IOException;

public class Test {

public static void main(String[] args) throws InterruptedException {
Monitor monitor = new Monitor();
new Thread(new WaitThread(monitor), "##########WAIT1############").start();
new Thread(new WaitThread(monitor), "##########WAIT2############").start();
new Thread(new SleepThread(), "##########SLEEP############").start();
new Thread(new BlockThread(), "##########BLOCK############").start();
new Thread(new RunTread(), "##########RUN############").start();
}
}

/**
* @author chuer
* @Description: 运行中的线程
* @date 2015年5月28日 下午2:41:32
* @version V1.0
*/

class RunTread implements Runnable{
long n = 0;
@Override
public void run(){
while(true){
n++;
}
}

}

/**
* @author chuer
* @Description: 读取流时阻塞的线程
* @date 2015年5月28日 下午2:42:06
* @version V1.0
*/

class BlockThread implements Runnable{
@Override
public void run(){
try {
System.in.read();
} catch (IOException e) {
e.printStackTrace();
}
}

}


/**
* @author chuer
* @Description: 睡着了的线程
* @date 2015年5月28日 下午2:42:25
* @version V1.0
*/

class SleepThread implements Runnable{

@Override
public void run() {
try {
Thread.sleep(Integer.MAX_VALUE);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}

/**
* @author chuer
* @Description: 等待中的线程
* @date 2015年5月28日 下午2:42:52
* @version V1.0
*/

class WaitThread implements Runnable {
Monitor monitor;
public WaitThread(Monitor monitor) {
this.monitor = monitor;
}
@Override
public void run() {
try {
monitor.setNum(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}

class Monitor {
private int num = 0;

public int getNum() {
return num;
}

public synchronized void setNum(int num) throws InterruptedException {
this.num = num;

if (this.num < 100) {
wait();
}
}

}

进入命令行,输入jps查看进程id,如下:

C:\Users\Administrator>jps
5632 Test
3316 Jps
4284

Test进程的id为5632

输入jstack命令如下所示:

C:\Users\Administrator>jstack 5632
2015-05-28 14:28:41
Full thread dump Java HotSpot(TM) Client VM (25.0-b70 mixed mode):

"DestroyJavaVM" #13 prio=5 os_prio=0 tid=0x0178d400 nid=0x954 waiting on condition [0x00000000]
java.lang.Thread.State: RUNNABLE

"##########RUN############" #12 prio=5 os_prio=0 tid=0x03e4c000 nid=0x1578 runnable [0x044bf000]
java.lang.Thread.State: RUNNABLE
at com.test.RunTread.run(Test.java:25)
at java.lang.Thread.run(Thread.java:744)

"##########BLOCK############" #11 prio=5 os_prio=0 tid=0x03e4b400 nid=0x1190 runnable [0x0413f000]
java.lang.Thread.State: RUNNABLE
at java.io.FileInputStream.readBytes(Native Method)
at java.io.FileInputStream.read(FileInputStream.java:234)
at java.io.BufferedInputStream.fill(BufferedInputStream.java:246)
at java.io.BufferedInputStream.read(BufferedInputStream.java:265)
- locked <0x10252290> (a java.io.BufferedInputStream)
at com.test.BlockThread.run(Test.java:36)
at java.lang.Thread.run(Thread.java:744)

"##########SLEEP############" #10 prio=5 os_prio=0 tid=0x03e48400 nid=0xd70 waiting on condition [0x0456f000]
java.lang.Thread.State: TIMED_WAITING (sleeping)
at java.lang.Thread.sleep(Native Method)
at com.test.SleepThread.run(Test.java:50)
at java.lang.Thread.run(Thread.java:744)

"##########WAIT2############" #9 prio=5 os_prio=0 tid=0x03e47000 nid=0xde4 in Object.wait() [0x0424f000]
java.lang.Thread.State: WAITING (on object monitor)
at java.lang.Object.wait(Native Method)
- waiting on <0x102b2400> (a com.test.Monitor)
at java.lang.Object.wait(Object.java:502)
at com.test.Monitor.setNum(Test.java:83)
- locked <0x102b2400> (a com.test.Monitor)
at com.test.WaitThread.run(Test.java:65)
at java.lang.Thread.run(Thread.java:744)

"##########WAIT1############" #8 prio=5 os_prio=0 tid=0x03e44000 nid=0xd9c in Object.wait() [0x0446f000]
java.lang.Thread.State: WAITING (on object monitor)
at java.lang.Object.wait(Native Method)
- waiting on <0x102b2400> (a com.test.Monitor)
at java.lang.Object.wait(Object.java:502)
at com.test.Monitor.setNum(Test.java:83)
- locked <0x102b2400> (a com.test.Monitor)
at com.test.WaitThread.run(Test.java:65)
at java.lang.Thread.run(Thread.java:744)

我们看到线程的状态有RUNNABLE,TIMED_WAITING,WAITING。

WAITING状态下有两种情况,一种是获得了对象锁,但是某些条件不达成而调用了wait方法。另外一种是对象锁被其他线程占用,此线程等待该锁释放。

TIMED_WAITING状态表示调用了线程的sleep方法,次线程会睡一段时间。

RUNNABLE状态表示线程正在执行,也有两种情况第一种是线程真正的在执行,另外一种是线程因为IO而阻塞。

我们可以通过线程的状态,来分析我们系统运行的情况,比如:IO阻塞的线程很多,那么就需要重新思考一下设计了。