原因:两个线程互相等待对方释放锁的状态
public class DeadLockDemo {
/** A锁 */
private static String A = "A";
/** B锁 */
private static String B = "B";
public static void main(String[] args) {
new DeadLockDemo().deadLock();
}
private void deadLock() {
Thread t1 = new Thread(new Runnable() {
@Override
public void run() {
synchronized (A) {
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (B) {
System.out.println("1");
}
}
}
});
Thread t2 = new Thread(new Runnable() {
@Override
public void run() {
synchronized (B) {
synchronized (A) {
System.out.println("2");
}
}
}
});
t1.start();
t2.start();
}
}
如上所示:
定义两个线程:t1和t2
随着程序的启动:
t1.start(); 进入run方法体,给A加锁,继续执行sleep函数,在sleep2秒内,线程t2争取到了cpu的使用权,继续执行t2的run方法体,给B加锁,再执行给A加锁,此时发现A已经被t1线程加上了锁,于是等待A释放锁,这时t1有轮到了cpu的使用权,执行给B加锁,但是B此时正在被线程t2加锁,于是等待t2释放锁。就这样,两个线程同时等待对方释放锁,造成了死锁。
如何避免死锁:
- 避免一个线程同时获得多个锁(比如例子中t1线程先获得A锁,后获得B锁)
- 避免一个线程在锁内同时占用多个资源,尽力一个锁占用一个资源
- 尝试定时锁,使用lock.tryLock(timeout)来代替使用内部锁机制
- 对于数据库锁,加锁解锁必须在一个数据库连接里面,否则解锁失败