什么是线程死锁?
死锁是指两个或者两个以上的线程在执行过程中,因为争夺资源而造成的互相等待的现象。如果没有外力作用下,这些线程会一直互相等待而无法继续运行下去。比如说线程A持有资源1,等待资源2。线程B持有资源2,等待资源1。且双方都不愿意放弃自己所持有的资源。
死锁的四个条件:
public class DeadLock2 {
private static volatile Object resourceA = new Object();
private static volatile Object resourceB = new Object();
public static void main(String[] args) {
new Thread(() -> {
synchronized (resourceA) {
System.out.println("获取resourceA的锁");
try {
Thread.sleep(1000L);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (resourceB) {
System.out.println("获取resourceB的锁");
//进入等待状态,此时会释放resource的监视器锁,但是不会释放resourceB的监视器锁
System.out.println("进行等待状态并释放resourceA的锁");
}
}
}).start();
new Thread(() -> {
synchronized (resourceB) {
try {
Thread.sleep(1000L);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("获取resourceB的锁");
synchronized (resourceA) {
System.out.println("获取resourceA的锁");
}
}
}).start();
}
}
然后就无法继续往下执行了,进入了死锁状态
如何避免死锁?
只需要破坏掉四个死锁条件中的一个构造死锁的必要条件即可。但是只有请求并持有条件和环路等待条件是可以被破坏的。资源的互斥条件和不可剥夺条件无法被破坏。
根据资源申请的有序性原则,可以让多个线程都使用相同的顺序去获取资源。比如说之前的线程1获取资源A再获取资源B,线程2获取资源B再获取资源A,这样有可能会发生死锁但是改成,线程1先获资源A,再获取B,线程2也先获取资源A再获取资源B.这样资源A只能被一个线程获取,只有获取到了资源A的线程才会继续去获取资源B,从而避免了死锁.同时破坏了环路等待条件和请求并持有条件获取超时则放弃。
提枪策马乘胜追击04-21 20:01
代码小兵92504-17 16:07
代码小兵98804-25 13:57
杨晶珍05-11 14:54