1、死锁是什么?
-
发生在并发中
-
互不相让:当两个(当两个(或更多)线程(或进程)相互持有对方所需的资源,又不主动释放,导致所有人都无法继续前进,导致程序陷入无尽的阻塞,这就是死锁)
2、多个线程造成死锁的情况
-
如果多个线程之间的依赖关系是环形,存在环路的锁的依赖关系,那么也就可以发生死锁
3、死锁的影响
死锁的影响在不同系统中是不一样的,这取决于系统对死锁的处理能力
-
数据库中:检测并放弃事务
-
JVM中:无法自动处理
4、几率不高但是危害大
-
不一定发生,但是遵循“墨菲定律”
-
一旦发生,多是高并发场景,影响用户多
-
整个系统崩溃,子系统崩溃,性能降低
-
压力测试无法找出所有潜在的死锁
5、死锁的代码
package deadlock;
//描述: 必定发生死锁的情况
public class MustDeadLock implements Runnable {
int flag = 1;
static Object o1 = new Object();
static Object o2 = new Object();
public static void main(String[] args) {
MustDeadLock r1 = new MustDeadLock();
MustDeadLock r2 = new MustDeadLock();
r1.flag = 1;
r1.flag = 0;
Thread thread1 = new Thread(r1);
Thread thread2 = new Thread(r2);
thread1.start();
thread2.start();
}
@Override
public void run() {
System.out.println("flag=" + flag);
if (flag == 1) {
synchronized (o1) {
try {
System.out.println("我拿到O1锁啦");
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (o2) {
System.out.println("我拿不到了");
}
}
}
if (flag == 0) {
synchronized (o2) {
try {
System.out.println("我拿了o2锁啦");
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (o1) {
System.out.println("拿不到了");
}
}
}
}
}
-
当类的对象flag=1时(thread1),先锁定o1,睡眠100毫秒,然后锁定o2
-
而thread1在睡眠的时候另一个flag=0的对象thread2线程启动,先锁定o2,睡眠100毫秒,等待thread1释放o1
-
thread1睡眠结束后需要锁定o2才能继续执行,而此时o2已被thread2锁定
-
thread2睡眠结束后需要锁定o1才能继续执行,而此时o1已被thread1锁定
-
thread1和thread2相互等待,都需要对方锁定资源才能继续执行,从而死锁