JVM调优实战场景二,死锁

死锁(Dead Lock):两个或以上的运算单元(进程、线程或协程),都在等待对方停止执行,以取得系统资源,但是没有一方提前退出。

1、模拟异常代码,开启两个线程,互相等待对方释放资源。sleep(2000)保证,两个线程第一时间能成功持有各自的第一个对象锁。


    private static Object lock1 = new Object();
    private static Object lock2 = new Object();

    /**
     * 线程互相等待对方释放资源,产生死锁
     * @return
     * @throws InterruptedException
     */
    @RequestMapping("/user/deadLock")
    public String deadLock() throws InterruptedException {
        new Thread(()->{
            synchronized (lock1){
                System.out.println("thread1 begin");
                try {
                    Thread.sleep(2000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                synchronized (lock2){
                    System.out.println("thread1 end");
                }
            }

        }).start();

        new Thread(()->{
            synchronized (lock2){
                System.out.println("thread2 begin");
                try {
                    Thread.sleep(2000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                synchronized (lock1){
                    System.out.println("thread2 end");
                }
            }
        }).start();

        return "sucess";
    }

 找到该java进程,pid=1737

ps -ef|grep java

 当页面发起如下请求后

http://101.132.143.77:8089/user/deadLock

通过日志,发现两个线程都开始了,但没有结束

 用jstack命令,可以直接分析该进程是否存在死锁 

jstack 1737

 底部分析出结果:found 1 deadlock,发现一个死锁

死锁的原因:

Thread-3等待获取对象<0x00000000c9f7c730>的锁,同时占有了对象<0x00000000c9f7c740>的锁。

Thread-4等待获取对象<0x00000000c9f7c740>的锁,同时占有了对象<0x00000000c9f7c730>的锁。

两个线程互相等待对方持有的资源

 此时线程3、4的状态都是BLOCKED

 线程的状态:

NEW:未启动的。不会出现先dump中。

RUNNABLE:运行中状态,在虚拟机内执行的。locked代表线程获得了锁。

BLOCKED:受阻塞并等待监视器锁。被某个锁给block住了。

WATING:无限期等待另一个线程执行特定操作。等待某个condition或monitor发生。

TIMED_WATING:有时限的等待另一个线程的特定操作。

TERMINATED:已退出的。

调用修饰:表示线程在方法调动时,额外的重要操作

locked<地址>目标:通过synchronized关键字,成功获取到了对象的锁,成为监视器的拥有者,在临界区内操作。

waiting to lock<地址>目标:通过synchronized关键字,没有获取到对象的锁,线程在监视器的进入区等待。在调用栈顶出现,线程状态为Blocked。

waiting on <地址>目标:通过synchronized关键字,成功获取到了对象的锁后,调用了wait方法,进入对象的等待区等待。在调用栈顶出现,线程状态为WAITING或TIMED_WATING。

parking to wat for<地址>目标:park是基本的线程阻塞原语,不通过监视器在对象上阻塞。

导出堆栈信息到文件:

jstack pid > dump.txt

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值