转载声明:文章来源https://blog.csdn.net/qq_51264307/article/details/129665182
死锁是多线程编程中的一个常见问题,它会导致程序停滞不前,无法继续执行下去。在实际开发中,死锁问题可能会导致程序崩溃,影响系统的稳定性和可靠性。
死锁是指两个或多个线程在互相等待对方释放资源的情况下,都无法继续执行下去的现象。死锁通常具有四个特点:互斥、占有并等待、不可剥夺和循环等待。
互斥条件:至少有一个资源是排他性的,即一次只能被一个进程使用。
占有并等待条件:进程已经占有至少一个资源,并且在等待另一个被其它进程占用的资源。
非剥夺条件:进程占有的资源不能被强行剥夺,只能在使用完后自愿释放。
循环条件:存在一种进程资源的环形等待链,每个进程都等待下一个进程所占有的资源。
举个例子:相信大家小时候都有看过《喜羊羊与灰太狼》,在古古怪界大作战中,想要进入古古怪界就需要将阴离子球和阳离子球合二为一来打开通往地底世界的大门
已知需要两个离子球合二为一才能进入地底世界,那么我们假设现在灰太狼手中掌握着阴离子球,而慢羊羊手中掌握着阳离子球(请不要在意字幕)
那么我们目前的状况是:
1.慢羊羊和灰太狼都不愿意和对方分享离子球(互斥条件)
2.慢羊羊和灰太狼都占有了一个离子球,并且都在等待对方放弃手中的离子球(占有并等待)
3.离子球是打开古古怪界的钥匙的同时也是强力的武器,慢羊羊和灰太狼都无法强行抢夺对方的离子球(非剥夺)
4.灰太狼在等待慢羊羊的阳离子球,慢羊羊也在等待灰太狼的阴离子球,形成了一个循环(循环)
那么可想而知下一步的发展,慢羊羊和灰太狼谁也无法将阴阳离子球合二为一,打开古古怪界的大门,局面就会这样僵持住
那么我们如果将两个离子球比作资源,将灰太狼和慢羊羊看作两个线程,这种僵持的局面就可以看作死锁了,即两个或更多线程,需要占有彼此的资源才能继续运行,然而因为资源被对方占有,它们都无法剥夺对方的资源,这样几个线程就都无法继续执行,形成了僵持的局面,这便是死锁
下面我们通过Java来实现一下这种死锁的产生
public class Demo {
private static Object lock1 = new Object();//阴离子球
private static Object lock2 = new Object();//阳离子球
public static void main(String[] args) {
Thread t1 = new Thread(() -> {//灰太狼
synchronized (lock1) {
System.out.println("灰太狼持有阴离子球");
try {
Thread.sleep(10);
} catch (InterruptedException e) {
}
System.out.println("灰太狼正在等待阳离子球");
synchronized (lock2) {
System.out.println("灰太狼同时得到了两个离子球,开启古古怪界的大门");
}
}
});
Thread t2 = new Thread(() -> {//慢羊羊
synchronized (lock2) {
System.out.println("慢羊羊持有阳离子球");
try {
Thread.sleep(10);
} catch (InterruptedException e) {
}
System.out.println("慢羊羊正在等待阴离子球");
synchronized (lock1) {
System.out.println("慢羊羊同时得到了两个离子球,开启古古怪界的大门");
}
}
});
t1.start();
t2.start();
}
}
在上述代码中,我们定义了两个线程分别代表慢羊羊和灰太狼,定义两个Object类分别代表阴离子球和阴离子球,让两者持有各自的离子球之后睡眠10ms来保证双方各自持有一个离子球的初始条件。
接下来我们分别启动两个线程
我们可以看到两个线程谁也无法获得对方所持有的锁,这便形成了死锁的局面。
帖子还没人回复快来抢沙发