Jstack use of the JVM

Summary: 

  Sometimes we need to look at the implementation of the jvm thread, for example, found that the CPU load on the server suddenly increased, there has been a deadlock, cycle of death and so on, how do we analyze it?

Because the program is running, there is no output from the log also do not see any problem, so we need to look at the implementation of the internal thread jvm, and then analyzed to find out the reason.

This time, we need the help of the jstack command, jstack role is to thread the case jvm running snapshots, and print it out;

In the state of Java threads are divided into a total of six species:

  初始状态:New,线程对象创建出来后,没有调用start方法,线程处于初始状态
  运行状态:包含了就绪状态和运行状态
    1.就绪状态:Ready,调用了Start方法,等待CPU分配资源
    2.运行状态:RUNNING,CPU分配资源给该线程,该线程处于运行状态
  阻塞状态 BLOCKED:
      线程获取资源,如果资源获取成功则正常运行,如果资源获取失败,就处于阻塞状态,等待什么时候获取到资源再变为运行状态
  等待状态 WAITING:线程手动调用了wait()方法,或者join()方法,这些方法都是主动进入等待状态,等待状态会将CPU资源让渡
      需要其他线程手动唤醒,notify(),notifyAll()唤起所有的等待线程
  超时等待状态 TIMED_WAITING:与等待状态相同,都是主动进入等待,也是需要其他线程唤醒,但是区别在与超时等待,如果超过了等待时间,则自动唤醒
      Thread.sleep(2000),在休眠等待时间内会将CPU资源让渡,然后等待时间结束自动进入运行状态
  终止状态 DIED:线程结束之后的状态

案例:解决死锁问题

  如果在生产环境发生了死锁,我们将看到的是部署的程序没有任何反应了,这个时候我们可以借助jstack进行分析,下面我们实战下查找死锁的原因。

构建死锁

  编写代码,启动2个线程,Thread1拿到了obj1锁,准备去拿obj2锁时,obj2已经被Thread2锁定,所以发送了死锁。

public class LockTest {
    //定义资源
    private static Object obj1=new Object();
    private static Object obj2=new Object();
    //线程A:先获取到资源1,然后休眠2s,再获取资源2
    private static class ThreadA implements Runnable {
        @Override
        public void run() {
            synchronized (obj1) {
                System.out.println("ThreadA获取到了OBJ1资源");

                try {
                    //休眠2s,因为我们要将CPU资源让渡出去,这样线程B就可以先抢占obj2资源
                    Thread.sleep(2000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }

                synchronized (obj2) {
                    System.out.println("ThreadA获取到了OBJ2资源");
                }
            }
        }
    }
    private static class ThreadB implements Runnable{
        @Override
        public void run() {
            synchronized (obj2){
                System.out.println("ThreadB获取到了OBJ2资源");

                try {
                    //休眠2s,因为我们要将CPU资源让渡出去,这样线程B就可以先抢占obj2资源
                    Thread.sleep(2000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }

                synchronized (obj1){
                    System.out.println("ThreadA获取到了OBJ1资源");
                }
            }
        }
    }

    public static void main(String[] args) {
        new Thread(new ThreadA()).start();
        new Thread(new ThreadB()).start();
    }
}

  运行出现死锁问题

   检查状态

   查看线程运行情况

   主要看如下:

   在输出的信息中,已经看到,发现了1个死锁

  可以清晰的看到:

    Thread-1获取了 <0x0517c5b0> 的锁,等待获取 <0x0517c5a8>这个锁

    Thread-0获取了 <0x0517c5a8> 的锁,等待获取 <0x0517c5b0>这个锁

  由此可见,发生了死锁

Guess you like

Origin www.cnblogs.com/ws1149939228/p/12410416.html