Java 死鎖的個人嘗試和理解

死鎖的例子是參考網上的例子,主要是想學習一下jstack命令來識別死鎖。

package basic;


import smallbird.Tools;


public class DeadThreadExample {


public static void main(String[] args) {
Thread1 t1=new Thread1();
Thread1 t2=new Thread1();
t1.mark=0;
t2.mark=1;
t1.start();
t2.start();
DeadLockThread r1=new DeadLockThread();
r1.setMark(0);
DeadLockThread r2=new DeadLockThread();
r2.setMark(1);
new Thread(r1).start();
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
System.out.println("sleep 10ms error");
};
new Thread(r2).start();
}
}

// 線程1

class Thread1 extends Thread{


int mark;

static Object obj1=new Object(),obj2=new Object();

@Override
public void run() {
if (mark==0) {
synchronized(obj1) {
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
System.out.println("object obj1 sleep error."+Tools.getNowDate(null));
}
}
synchronized(obj2) {
System.out.println("obj2 mark:"+mark+". "+Tools.getNowDate(null));
}
} else if (mark==1) {
synchronized(obj2) {
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
System.out.println("object obj2 sleep error."+Tools.getNowDate(null));
}
}
synchronized(obj1) {
System.out.println("obj1 mark:"+mark+". "+Tools.getNowDate(null));
}
}
System.out.println("End Thread: "+this.getName()+"."+Tools.getNowDate(null));
}
}

// 線程2
class DeadLockThread implements Runnable{


int mark;

static Object obj1=new Object(),obj2=new Object();

@Override
public void run() {
if (mark==0) {
synchronized(obj1) {
try {
Thread.sleep(1000*180);
} catch (InterruptedException e) {
e.printStackTrace();
System.out.println("object obj1 sleep error."+Tools.getNowDate(null));
}
synchronized(obj2) {
System.out.println("obj2 mark:"+mark+". "+Tools.getNowDate(null));
}
}

} else if (mark==1) {
synchronized(obj2) {
System.out.println("obj1 mark:"+mark+". "+Tools.getNowDate(null));
synchronized(obj1) {
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
System.out.println("object obj2 sleep error."+Tools.getNowDate(null));
}

}
}
}
System.out.println("End ."+Tools.getNowDate(null));
}


public int getMark() {
return mark;
}


public void setMark(int mark) {
this.mark = mark;
}

}

使用Eclipse開發,Run後,在任務管理器找到pid,可以執行兩次,pid沒有變化的估計是Eclipse進程用到的,另一個javaw.exe就是我們Run的進程。

cmd命令窗口,jstack -l  3616

輸出截圖:





主要看第3張截圖,發現了死鎖。

線程類1沒有出現死鎖,線程類2出現了死鎖。我電腦是i3處理器,所以線程類1執行很快,沒有遇到死鎖。

控制檯打印:

obj1 mark:1. 2015-06-24 21:26:58,051
obj2 mark:0. 2015-06-24 21:26:58,503
End Thread: Thread-0.2015-06-24 21:26:58,503
obj1 mark:1. 2015-06-24 21:26:58,503
End Thread: Thread-1.2015-06-24 21:26:58,503

這個是已經等了有差不多10分鐘左右,還沒有執行完成。關鍵是線程類2中等待了3分鐘時間,這個導致多核CPU也不能快速執行完。

Found one Java-level deadlock:
=============================
"Thread-3":
  waiting to lock monitor 0x000000000052a8f0 (object 0x00000000f00f1d70, a java.
lang.Object),
  which is held by "Thread-2"
"Thread-2":
  waiting to lock monitor 0x000000000052a998 (object 0x00000000f00f1d80, a java.
lang.Object),
  which is held by "Thread-3"


Java stack information for the threads listed above:
===================================================
"Thread-3":
        at basic.DeadLockThread.run(DeadThreadExample.java:92)
        - waiting to lock <0x00000000f00f1d70> (a java.lang.Object)
        - locked <0x00000000f00f1d80> (a java.lang.Object)
        at java.lang.Thread.run(Thread.java:662)
"Thread-2":
        at basic.DeadLockThread.run(DeadThreadExample.java:83)
        - waiting to lock <0x00000000f00f1d80> (a java.lang.Object)
        - locked <0x00000000f00f1d70> (a java.lang.Object)
        at java.lang.Thread.run(Thread.java:662)


Found 1 deadlock.



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章