死鎖原因
Java發(fā)生死鎖的根本原因是:在申請鎖時發(fā)生了交叉閉環(huán)申請还栓。即線程在獲得了鎖A并且沒有釋放的情況下去申請鎖B梅肤,這時,另一個線程已經(jīng)獲得了鎖B域携,在釋放鎖B之前又要先獲得鎖A棺弊,因此閉環(huán)發(fā)生晶密,陷入死鎖循環(huán)。
監(jiān)控死鎖
VisualVM監(jiān)控工具有明顯線程死鎖提醒模她,也可監(jiān)控到發(fā)生死鎖的線程稻艰、類、代碼行數(shù)缝驳、數(shù)據(jù)類型连锯。
分析死鎖
-
VisualVM生成threaddump,查找死鎖代碼塊內(nèi)存地址
- VisualVM生成heapdump, 使用OQL查看被死鎖對象的值和引用
select heap.findObject("0x00000006c0276428")
- 使用OQL的另一種方法
jmap -dump:live,file=/data/test.map <jps端口號>
jhat /data/test.map
瀏覽器訪問 http://ip:7000/
示例代碼
/*
* 線程死鎖等待演示
*/
static class SynAddRunalbe implements Runnable {
int a, b;
public SynAddRunalbe(int a, int b) {
this.a = a;
this.b = b;
}
@Override
public void run() {
synchronized (Integer.valueOf(a)) {
synchronized (Integer.valueOf(b)) {
System.out.println(a + b);
}
}
}
public static void main(String[] args) throws Exception {
for (int i=0;i< 100; i++) {
new Thread(new SynAddRunalbe(1, 2)).start();
new Thread(new SynAddRunalbe(2, 1)).start();
}
}
公號:大道測試