什么是死锁
两个或多个线程持有当前锁不释放,尝试去申请其他线程的锁,且只有申请到其他线程锁时才可以释放当前锁,因此形成死循环,也即是死锁
死锁例子:
// 死锁
public class SolveDeadLockDemo {
// 锁A
private static final String LOCK_A = "lock_a";
// 锁B
private static final String LOCK_B = "lock_b";
// 方法A
public void methodA(){
synchronized (LOCK_A){
System.out.println("方法A调用锁A");
// sleep 交出CPU使用权,不释放锁
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (LOCK_B){
System.out.println("方法A尝试调用锁B");
}
}
}
// 方法B
public void methodB(){
synchronized (LOCK_B){
System.out.println("方法B调用锁B");
// sleep 交出CPU使用权,不释放锁
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (LOCK_A){
System.out.println("方法B尝试调用锁A");
}
}
}
public static void main(String[] args) {
System.out.println("主线程开启+"+Thread.currentThread().getName());
SolveDeadLockDemo deadLockDemo = new SolveDeadLockDemo();
// 线程A开启
new Thread(deadLockDemo::methodA).start();
// 线程B开启
new Thread(deadLockDemo::methodB).start();
}
}
解决方法
- 调整申请锁的范围
- 调整申请锁的顺序
// 死锁
public class SolveDeadLockDemo {
// 锁A
private static final String LOCK_A = "lock_a";
// 锁B
private static final String LOCK_B = "lock_b";
// 方法A
public void methodA(){
synchronized (LOCK_A){
System.out.println("方法A调用锁A");
// sleep 交出CPU使用权,不释放锁
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
synchronized (LOCK_B){
System.out.println("方法A尝试调用锁B");
}
}
// 方法B
public void methodB(){
synchronized (LOCK_B){
System.out.println("方法B调用锁B");
// sleep 交出CPU使用权,不释放锁
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
synchronized (LOCK_A){
System.out.println("方法B尝试调用锁A");
}
}
public static void main(String[] args) {
System.out.println("主线程开启+"+Thread.currentThread().getName());
SolveDeadLockDemo deadLockDemo = new SolveDeadLockDemo();
// 线程A开启
new Thread(deadLockDemo::methodA).start();
// 线程B开启
new Thread(deadLockDemo::methodB).start();
}
}