运行了一段时间的程序,可能因为不小心的一些修改,造成死锁,本人就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教程就结束了
感谢您的耐心阅读,如果您发现文章中有一些没表述清楚的,或者是不对的地方,请给我留言,你的鼓励是作者写作最大的动力,
如果您认为本文质量不错,读后觉得收获很大,不妨小额赞助我一下,让我更有动力继续写出高质量的文章。- 支付宝
- 微信
作 者 :
原文出处 :
创作时间:2016-2-15
更新时间:2016-2-15