被遗忘的凉白开
文章22
标签34
分类3
面试官又问了:什么是死锁?

面试官又问了:什么是死锁?

今天是端午节啦,祝大家端午安康喽,大家都应该吃到自己的粽子了吧!你们粽意的我又来了,今天我们学习死锁,死锁的问题在高并发的业务场景中是很容易遇到,而且不易排查的问题!希望本文对XDM有用!

这是我参与更文挑战的第14天,活动详情查看: 更文挑战

XDM,今天是端午节啦,祝大家端午安康喽,大家都应该吃到自己的粽子了吧!你们粽意的我又来了,今天我们学习死锁

1、什么是死锁

死锁是指两个或两个以上的进程在执行过程中,由于竞争资源或者由于彼此通信而造成的一种阻塞现象,若无外力作用,它们都将无法推进下去。此时系统处于死锁状态或系统产生了死锁

上面的概念说的很规范,不容易理解,使用代码来举例子相比较而言会更容易理解一些

public class NormalDeadLock {

    private static Object No13 = new Object();//第一个锁
    private static Object No14 = new Object();//第二个锁

    //第一个拿锁的方法
    private static void do1() throws InterruptedException {
        String threadName = Thread.currentThread().getName();
        synchronized (No13){
            System.out.println(threadName+" get nO13");
            Thread.sleep(100);
            synchronized (No14){
                System.out.println(threadName+" get nO14");
            }
        }
    }

    //第二个拿锁的方法
    private static void do2() throws InterruptedException {
        String threadName = Thread.currentThread().getName();
        synchronized (No14){
            System.out.println(threadName+" get nO13");
            Thread.sleep(100);
            synchronized (No13){
                System.out.println(threadName+" get nO14");
            }
        }
    }



}

两个线程线程A,和线程B,分别执行了do1,和do2,线程A拿到了13号锁,线程B拿到了14号锁,这样线程在拿14号锁的时候拿不到了,就进入了阻塞状态了,线程B也拿不到13号锁也进入了阻塞状态,这样两个线程都不干活了,谁也不让谁,就一直在这耗着浪费了资源

2、造成死锁的必要条件

2.1、操作者数 >=2,资源数>=2 并且资源数<=操作者数

如果只有一个操作者,肯定不会造成资源竞争,如果只有线程A拿到13号锁直接也就拿到了14号锁,直接干活就是了,如果可用资源数大于操作者数,也不会造成死锁,比如又来了个15号锁,也能满足do2的业务逻辑,那么do2得到14 号锁接着去获取15号锁,跟线程A就没有关系了也就产生不了死锁

2.2、争夺资源的顺序不对

如果我们把锁的顺序调换一下,把do2的第一层锁变成13,线程A 和线程B一开始都去争夺13号锁,线程A抢到了,线程A干完了事,线程B自然而然也就能拿到13号锁继续干它的事,也就不会产生死锁

2.3、拿到资源不放手

我们再想一下,如果线程A比较谦让,等了一段时间,没有拿到14号锁,它把13号锁让出去了,让线程B先执行,死锁的问题也会得到解决

总结

死锁的产生的必要条件就是以上三个,想要解决死锁问题,打破三个条件的其中一个就可以解决死锁问题,死锁的问题在高并发的业务场景中是很容易遇到,而且不易排查的问题!希望本文对XDM有用!

本文作者:被遗忘的凉白开
本文链接:http://amszlk.com/2021/06/24/mian-shi-guan-you-wen-liao-shi-me-shi-si-suo/
版权声明:本文采用 CC BY-NC-SA 3.0 CN 协议进行许可