死鎖的例子是參考網上的例子,主要是想學習一下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.