死锁
死锁的由来定位方法避免死锁
死锁的由来
在多线程场景中,多个线程互相持有对方需要的锁,从而造成了阻塞。严重影响了性能。
常见的死锁:顺序死锁,动态死锁(转账)
public class Test {
public static void main(String
[] args
) {
Object a1
=new Object();
Object a2
=new Object();
A t1
=new A(a1
,a2
);
B t2
=new B(a1
,a2
);
t1
.setName("t1");
t2
.setName("t2");
t1
.start();t2
.start();
}
}
class A extends Thread{
Object o1
;
Object o2
;
public A(Object o1
, Object o2
) {
this.o1
= o1
;
this.o2
= o2
;
}
public void run(){
synchronized (o1
){
System
.out
.println("线程t1占用了o1");
try {
Thread
.sleep(1000);
} catch (InterruptedException e
) {
e
.printStackTrace();
}
synchronized (o2
){
System
.out
.println("线程t1占用了o2");
}
}
}
}
class B extends Thread{
Object o1
;
Object o2
;
public B(Object o1
, Object o2
) {
this.o1
= o1
;
this.o2
= o2
;
}
public void run(){
synchronized (o2
){
System
.out
.println("线程t2占用了o2");
try {
Thread
.sleep(1000);
} catch (InterruptedException e
) {
e
.printStackTrace();
}
synchronized (o1
){
System
.out
.println("线程t2占用了o1");
}
}
}
线程A占用o1锁,想要占用o2锁。线程B占用o2锁,想要占用o1锁。
问题:线程B没有释放o2锁那么线程A就无法完成。线程A没有释放o1锁,线程B也没有办法完成。就这样造成了死锁。
定位方法
通过jstack分析线程的栈信息; 或者使用ThreadMXBean相关的api在程序中打印出相关的死锁信息;
避免死锁
一、尽量不要嵌套锁。 二、如果要使用嵌套锁,注意顺序关系。 三、对代码进行审查,提前发现然后修正代码。