转载

【深入浅出-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): 检测死锁

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

打开Dump文件,发现如下:

【深入浅出-VisualVM】(6): 检测死锁

这是一个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教程就先到此结束啦,以后有时间再去补充啦~~~

原文  http://mousycoder.com/2016/02/15/thinking-in-visualvm/thinking-in-visualvm-6/
正文到此结束
Loading...