java高*之jstack命令使用

时间:2022-11-08 17:20:32

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阻塞的线程很多,那么就需要重新思考一下设计了。