• jstack监控JVM线程的运行情况


    1.通过jstack监控JVM当中线程的运行情况  jstack 进程ID


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

                    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();
                        }
                    }

    线程A拿到obj1时休眠俩秒

    同时线程B拿到obj2也休眠俩秒

    当他们休眠结束时都想拿对方锁住的资源

    这样就造成了死锁


                2.1监控当前程序的线程运行情况
                    jstack 进程ID,查看到如下信息:


                      Java stack information for the threads listed above:
    ===================================================
    "Thread-1":
            at com.chx.LockTest$ThreadB.run(LockTest.java:41)
            - waiting to lock <0x000000075693d5a0> (a java.lang.Object)
            - locked <0x000000075693d5b0> (a java.lang.Object)
            at java.lang.Thread.run(Thread.java:748)
    "Thread-0":
            at com.chx.LockTest$ThreadA.run(LockTest.java:22)
            - waiting to lock <0x000000075693d5b0> (a java.lang.Object)
            - locked <0x000000075693d5a0> (a java.lang.Object)
            at java.lang.Thread.run(Thread.java:748)

    Found 1 deadlock.

    这样就定位到了线程,发现了死锁

  • 相关阅读:
    Mysql开启日志
    amfphp传递负数的bug
    linux /var/spool/clientmqueue 目录占大量空间
    WinXP SSH连接不上虚拟机的解决方法
    批量数据替换助手V1.0版发布
    也谈反射的应用场景
    反射+特性打造简洁的AJAX调用
    文本处理之利器正则表达式闪亮登场
    关于缩略图的生成与访问策略的一些经验分享
    装饰模式个人的一些理解
  • 原文地址:https://www.cnblogs.com/chx9832/p/12411279.html
Copyright © 2020-2023  润新知