死锁是指多个线程循环等待它方占有的资源而无限期地僵持下去的局面。如有o1与o2两个资源,线程t1持有o1后,如果再持有o2,就能正常完成操作,不巧,这时另一个线程t2已经持有o2,若再持有o1,则能完成操作,这样就互相等对方持有的资源,产生死锁。
一 、 示例。
1、定义资源
package thread.deadlock;
public class CustomObject {
}
2、线程1实现
package thread.deadlock;
public class LockT1 implements Runnable{
private CustomObject o1;
private CustomObject o2;
public LockT1(CustomObject o1, CustomObject o2) {
super();
this.o1 = o1;
this.o2 = o2;
}
@Override
public void run() {
// TODO Auto-generated method stub
synchronized(o1){
try {
System.out.println(Thread.currentThread().getName()+ " hold o1");
Thread.sleep(5000);
synchronized(o2){
System.out.println(Thread.currentThread().getName()+ " hold o2");
}
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
package thread.deadlock;
public class LockT2 implements Runnable{
private CustomObject o1;
private CustomObject o2;
public LockT2(CustomObject o1, CustomObject o2) {
super();
this.o1 = o1;
this.o2 = o2;
}
@Override
public void run() {
// TODO Auto-generated method stub
synchronized(o2){
try {
System.out.println(Thread.currentThread().getName()+ " hold o2");
Thread.sleep(1000);
synchronized(o1){
System.out.println(Thread.currentThread().getName()+ " hold o1");
}
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
3、跑起来
package thread.deadlock;
public class T {
public static void main(String[] args) {
CustomObject o1 = new CustomObject();
CustomObject o2 = new CustomObject();
Thread t1 = new Thread(new LockT1(o1,o2),"t1");
Thread t2 = new Thread(new LockT2(o1,o2),"t2");
t1.start();
t2.start();
}
}
二、排查
工具:jstack 或 jvisualvm.exe
dump线程执行信息
Found one Java-level deadlock:
=============================
"t2":
waiting to lock monitor 0x000000000226b168 (object 0x00000007ab11de78, a thread.deadlock.CustomObject),
which is held by "t1"
"t1":
waiting to lock monitor 0x0000000010bbe3e8 (object 0x00000007ab11de88, a thread.deadlock.CustomObject),
which is held by "t2"
可以看到t1和t2线程相互持有待的资源,thread.deadlock.CustomObject 为锁住的资源所属的类