【VisualVM 简明教程】(6): 检测死锁

运行了一段时间的程序,可能因为不小心的一些修改,造成死锁,本人就VisualVM简单的介绍下死锁的检测。

死锁程序

package jvisualVM;
 
public class DeadLock {
    public static void main(String[] args) {
        Resource r1 = new Resource();
        Resource r0 = new Resource();
 
        Thread myTh1 = new LockThread1(r1, r0);
        Thread myTh0 = new LockThread0(r1, r0);
 
        myTh1.setName("DeadLock-1 ");
        myTh0.setName("DeadLock-0 ");
 
        myTh1.start();
        myTh0.start();
    }
}
 
    class Resource {
        private int i;
 
        public int getI() {
            return i;
        }
 
        public void setI(int i) {
            this.i = i;
        }
 
    }
 
    class LockThread1 extends Thread {
        private Resource r1, r2;
 
        public LockThread1(Resource r1, Resource r2) {
            this.r1 = r1;
            this.r2 = r2;
        }
 
        @Override
        public void run() {
            int j = 0;
            while (true) {
                synchronized (r1) {
                    System.out.println("The first thread got r1's lock " + j);
                    synchronized (r2) {
                        System.out.println("The first thread got r2's lock  " + j);
                    }
                }
                j++;
            }
        }
 
    }
 
    class LockThread0 extends Thread {
        private Resource r1, r2;
 
        public LockThread0(Resource r1, Resource r2) {
            this.r1 = r1;
            this.r2 = r2;
        }
 
        @Override
        public void run() {
            int j = 0;
            while (true) {
                synchronized (r2) {
                    System.out.println("The second thread got r2's lock  " + j);
                    synchronized (r1) {
                        System.out.println("The second thread got r1's lock" + j);
                    }
                }
                j++;
            }
        }
 
    }

分析

【VisualVM 简明教程】(6): 检测死锁_第1张图片

本地的话vvm会立刻提醒有死锁程序,远程的话,生成线程Dump文件即可,发现是线程DeadLock-0,DeadLock-1处于监控状态,很有可能是造成死锁的线程,点击线程Dump。

打开Dump文件,发现如下:
【VisualVM 简明教程】(6): 检测死锁_第2张图片

这是一个java级别的死锁(java代码造成的),DeadLock-0 线程想给公共资源(0x00000007d7a080d8, a com.mousycoder.server.thead.Resource)加锁,但是这个资源还是被DeadLock-1线程占有。DeadLock-1线程想去给公共资源(object 0x00000007d7a080e8, a com.mousycoder.server.thead.Resource)加锁,但是这个资源被DeadLock占有。

并且分别给出了,线程的堆栈,就可以很快定位代码。

避免死锁策略

死锁是并发程序设计中十分常见的逻辑错误。

  • 避免嵌套锁

本例子就是嵌套锁,当你已经给一个资源上锁后,避免再去锁住另一个。

  • 只对需要的地方加锁

比如只是要对特定的字段加锁,就不要锁住整个obejct。

  • 避免无限期等待

当一个线程必须等待另外一个线程的时候,最好加上一个等待时间。超过时间,自动放弃本操作,避免进程悬挂。

  • 把大事务拆成小事务

早提交,早回滚。

整个VisaulVm教程就结束了


感谢您的耐心阅读,如果您发现文章中有一些没表述清楚的,或者是不对的地方,请给我留言,你的鼓励是作者写作最大的动力,
如果您认为本文质量不错,读后觉得收获很大,不妨小额赞助我一下,让我更有动力继续写出高质量的文章。

  • 支付宝

【VisualVM 简明教程】(6): 检测死锁_第3张图片

  • 微信

【VisualVM 简明教程】(6): 检测死锁_第4张图片

作 者 : @mousycoder

原文出处 : http://mousycoder.com/2016/02...

创作时间:2016-2-15

更新时间:2016-2-15

你可能感兴趣的:(java)