运行了一段时间的程序,可能因为不小心的一些修改,造成死锁,本人就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++; } } }
本地的话vvm会立刻提醒有死锁程序,远程的话,生成线程Dump文件即可,发现是线程DeadLock-0,DeadLock-1处于监控状态,很有可能是造成死锁的线程,点击线程Dump。
打开Dump文件,发现如下:
这是一个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教程就先到此结束啦,以后有时间再去补充啦~~~