经典面试题-死锁
目录
1.什么是死锁?
2.形成死锁的四个必要条件
3.死锁的三种情况
第一种情况:
举例:
举例:
第二种情况:两个线程 两把锁
举例:
第三种情况:N个线程 M把锁
哲学家进餐问题
1.什么是死锁?
死锁是指在并发系统中,两个或多个进程(或线程)互相等待对方所占有的资源而无法继续执行的情况。这种情况下,每个进程都在等待其他进程释放资源,导致所有进程都无法向前推进。
2.形成死锁的四个必要条件
1.互斥使用,获取锁的过程是互斥的。一个线程拿到了一把锁,另一个线程也想获取这把锁,就需要阻塞等待。
2.不可抢占。一个线程拿到了锁之后,只能主动解锁,不能让别的线程强行把锁抢走。
3.请求保持。一个线程拿到了锁A之后,在持有A的前提下,尝试获取B。
4.循环等待:存在一个进程链,每个进程都在等待下一个进程所占有的资源。
3.死锁的三种情况
第一种情况:
如果锁是不可进重入锁,并且一个线程对这把锁加锁了两次,那么它就会出现死锁的情况。
如果不是不可进重入锁。会出现下面的情况
举例:
package 多线程;
//死锁
public class ThreadDemo15 {public static void main(String[] args) {Object locker =new Object();Thread t = new Thread(()-> {synchronized (locker) {synchronized (locker) {//当前由于事同一个线程,此时锁对象,就知道第二次加锁的线程,就是持有锁的线程。第二次操作会直接放行。System.out.println("hello");}}//在这里解锁});t.start();}
}
它就会打印一个hello。

如果是不可重进入锁
举例:
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;public class DeadlockExample {private static Lock lock = new ReentrantLock();public static void main(String[] args) {Thread thread = new Thread(() -> {lock.lock();System.out.println("Thread is holding the lock");// 尝试再次获取锁,会导致死锁lock.lock(); System.out.println("This line will not be reached");lock.unlock();});thread.start();}
}
他就不会输出东西。
第二种情况:两个线程 两把锁
线程1 获取到 锁A
线程2 获取到 锁B
接下来,1 尝试获取B,2尝试获取A ,就会出现死锁。
一旦出现死锁,线程就会被卡住无法继续工作。
举例:
package 多线程;
//死锁
public class ThreadDemo16 {public static void main(String[] args) {Object A = new Object();Object B = new Object();Thread t1 = new Thread(()->{synchronized (A){try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}//A尝试获取B,并没有释放Asynchronized (B){System.out.println("t1 拿到了B");}}});Thread t2 = new Thread(()->{synchronized (B){//约定加锁顺序,try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}synchronized (A){System.out.println("t2 拿到了A");}}});t1.start();t2.start();}
}
当我们输出结果就会发现它一直没有输出任何东西。 当t1线程持有A的锁资源时,它尝试获取B,而同时t2线程持有B的锁资源,它尝试获取A,这样两个线程相互等待对方的锁资源,导致死锁的情况发生。

如何去解决这个问题呢,关键就在于死锁形成的四个必要条件,只要我们可以打破这四个必要条件,就不会形成死锁。这个题,我们约定好加锁的顺序的话,就不会出现死锁。
package 多线程;
//死锁
public class ThreadDemo16 {public static void main(String[] args) {Object A = new Object();Object B = new Object();Thread t1 = new Thread(()->{synchronized (A){try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}//A尝试获取B,并没有释放Asynchronized (B){System.out.println("t1 拿到了B");}}});Thread t2 = new Thread(()->{synchronized (A){//约定加锁顺序,try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}synchronized (B){System.out.println("t2 拿到了A");}}});t1.start();t2.start();}
}
当t1线程获取到A对象的锁资源后,它会尝试获取B对象的锁资源,但是此时B对象已经被t2线程锁住了,因此t1线程会进入等待状态。当t2线程获取到B对象的锁资源后,它会尝试获取A对象的锁资源,此时A对象没有被锁住,因此t2线程可以获取到A对象的锁资源,执行完成后释放锁资源,然后t1线程才能继续执行,获取B对象的锁资源,避免了死锁的发生。

第三种情况:N个线程 M把锁
哲学家进餐问题

描述了五位哲学家围坐在一张圆桌旁,每个人面前都有一碗米饭和一只筷子。这些哲学家只能用左手和右手各拿一只筷子进食。问题是,如何安排他们的动作,使得每个哲学家都能进餐?
问题分析 :
由问题描述我们可以知道,一共有五个哲学家,也就是五个进程;五只筷子,也就是五个临界资源;因为哲学家想要进餐,必须要同时获得左边和右边的筷子,这就是要同时进入两个临界区(使用临界资源),才可以进餐。
问题解决:
- 一次只允许两个哲学家进餐,并且要求他们都拿到右手边的筷子后才能开始进食。
- 引入一个仲裁者,即一个额外的实体负责协调哲学家的动作,以避免死锁的发生。
- 使用资源分配算法,例如Dijkstra的银行家算法,来确保每个哲学家都能有足够的资源进餐。
希望大家多多支持! 
相关文章:
经典面试题-死锁
目录 1.什么是死锁? 2.形成死锁的四个必要条件 3.死锁的三种情况 第一种情况: 举例: 举例: 第二种情况:两个线程 两把锁 举例: 第三种情况:N个线程 M把锁 哲学家进餐问题 1.什么是死锁&…...
mysql面试题合集-基础
前言 工作很忙,本质还是自己比较懒惰,很久没更新博客了。近期打算面试,换个工作环境,那就先从面试题开始吧,后续也会逐渐更新自己在工作中的一些经验感悟。接下来切入主题,由于长期做前台开发工作…...
点灯大师(STM32)
这段代码是用于STM32F10x系列微控制器的C语言程序,目的是初始化GPIOC的Pin 13为输出,并设置其输出高电平。以下是对代码的逐行解释: #include "stm32f10x.h" 这一行引入了STM32F10x设备的头文件,包含了用于STM32F10x系…...
@EnableEurekaServer
定义:EnableEurekaServer注解是Spring Cloud中的一个注解,用于将Spring Boot应用程序指定为Eureka服务器。 Eureka服务器是一个服务注册中心,也被称为发现服务器,管理和协调微服务。保存有关所有客户端服务应用程序的信息。 每个…...
Java中的接口
六. 接口 特性1 - 解决单继承 语法如下 interface A {public default void a() {} }interface B {public default void b() {} }// C 从 A, B 两个接口重用方法 a() 和 b() class C implements A, B {}解决之前的问题 public class TestInterface1 {public static void mai…...
Linux笔记之bash脚本中的-e、和
Linux笔记之bash脚本中的-e、&和&& code review! 文章目录 Linux笔记之bash脚本中的-e、&和&&1.&和&&2.-e 1.&和&& 在Linux bash脚本中,&符号有几个不同的用途,这里列举了一些常见的情况…...
mapstruct自定义转换,怎样将String转化为List
源码:https://gitee.com/cao_wen_bin/test 最近在公司遇到了这样一个为题,前端传过来的是一个List<Manager>,往数据库中保存到时候是String,这个String使用谷歌的json转化器。 当查询的时候在将这个数据库中String的数据以List<Mana…...
torch.matmul和torch.bmm区别
torch.matmul可用于4维数组的相乘,而torch.bmm只能用户3维数组的相乘,以/home/tiger/.local/lib/python3.9/site-packages/transformers/models/vit/modeling_vit.py中的ViTSelfAttention实现为例,在transpose_for_scores之前的shape是(batch…...
k8s学习(RKE+k8s+rancher2.x)成长系列之概念介绍(一)
一、前言 本文使用国内大多数中小型企业使用的RKE搭建K8s并拉起高可用Rancher2.x的搭建方式,以相关技术概念为起点,实际环境搭建,程序部署为终点,从0到1的实操演示的学习方式,一步一步,保姆级的方式学习k8…...
PHP - Yii2 异步队列
1. 前言使用场景 在 PHP Yii2 中,队列是一种特殊的数据结构,用于处理和管理后台任务。队列允许我们将耗时的任务(如发送电子邮件、push通知等)放入队列中,然后在后台异步执行。这样可以避免在处理大量请求时阻塞主应用…...
leetcode560和为k的子数组
class Solution { public:int subarraySum(vector<int>& nums, int k) {unordered_map<int,int>mp;mp[0]1;int count0,pre0;for(auto& x:nums){prex;if(mp.find(pre-k)!mp.end()){countmp[pre-k];}mp[pre];}return count;} }; 一个超级好的思路࿰…...
【ProtoBuf】使用指南
一.什么是ProtoBuf 特点:ProtoBuf是用于序列化和反序列化的一种方法,类似xml和json,但是效率更高,体积更小。ProtoBuf具有语⾔⽆关、平台⽆关,扩展性、兼容性好等特点。 ProtoBuf是需要依赖通过编译生成的头文件和源…...
Buffer Pool
Buffer Pool 概念free链表flush链表LRU链表chunk 概念 MySQL在启动时向操作系统申请的一片连续的内存,默认128M。然后将这块内存分为一个一个缓冲页(16KB,因为页就是16KB的)。再为每个缓冲页创建对应的控制块用于管理。比如第一次查询数据之后ÿ…...
jetson-inference----docker内运行分类任务
系列文章目录 jetson-inference入门 jetson-inference----docker内运行分类任务 文章目录 系列文章目录前言一、进入jetson-inference的docker二、分类任务总结 前言 继jetson-inference入门 一、进入jetson-inference的docker 官方运行命令 进入jetson-inference的docker d…...
Python脚本之操作Redis Cluster【二】
本文为博主原创,未经授权,严禁转载及使用。 本文链接:https://blog.csdn.net/zyooooxie/article/details/112484045 之前写过一篇 使用redis-py来操作redis集群, https://blog.csdn.net/zyooooxie/article/details/123760358 &am…...
认识数学建模
文章目录 1 什么是数学建模2 数学建模的比赛形式3 参加数学建模的好处4 数学建模的流程5 数学建模成员分工6 数学建模常用软件7 数学建模竞赛7.1 美国大学生数学建模竞赛7.2 MathorCup高校数学建模挑战赛7.3 华中杯大学生数学建模挑战赛7.4 认证杯数学建模网络挑战赛7.5 华东杯…...
计算机工作原理解析和解剖(基础版)
我们会从软件⼯程师的⻆度解释计算机是如何⼯作的,我们的主要⽬标既不是期待 ⼤家可以造出⾃⼰的计算机,也不是介绍如何编程,⽽是希望让⼤家了解计算机的核⼼⼯作机制后,打破计算机的神秘感,并且有利于理解我们平时编程…...
外网ssh远程连接服务器
文章目录 外网ssh远程连接服务器一、前言二、配置流程1. 在服务器上安装[cpolar](https://www.cpolar.com/)客户端2. 查看版本号,有正常显示版本号即为安装成功3. token认证4. 简单穿透测试5. 向系统添加服务6. 启动cpolar服务7. 查看服务状态8. 登录后台࿰…...
滴滴基于 Ray 的 XGBoost 大规模分布式训练实践
背景介绍 作为机器学习模型的核心代表,XGBoost 在滴滴众多策略算法业务场景中发挥着至关重要的作用。因此,保障并持续提升 XGBoost 模型的离线训练及在线推理稳定性一直是机器学习平台的重点工作。同时,面对多样化的业务场景定制需求和数据规…...
k8s从入门到实践
k8s从入门到实践 介绍 Kubernetes(简称k8s)和Docker Swarm是两个流行的容器编排工具,它们都可以帮助用户管理和部署分布式应用,尤其是基于容器的应用。以下是两者的主要特点和对比: Kubernetes (k8s): 开…...
网络六边形受到攻击
大家读完觉得有帮助记得关注和点赞!!! 抽象 现代智能交通系统 (ITS) 的一个关键要求是能够以安全、可靠和匿名的方式从互联车辆和移动设备收集地理参考数据。Nexagon 协议建立在 IETF 定位器/ID 分离协议 (…...
深入剖析AI大模型:大模型时代的 Prompt 工程全解析
今天聊的内容,我认为是AI开发里面非常重要的内容。它在AI开发里无处不在,当你对 AI 助手说 "用李白的风格写一首关于人工智能的诗",或者让翻译模型 "将这段合同翻译成商务日语" 时,输入的这句话就是 Prompt。…...
盘古信息PCB行业解决方案:以全域场景重构,激活智造新未来
一、破局:PCB行业的时代之问 在数字经济蓬勃发展的浪潮中,PCB(印制电路板)作为 “电子产品之母”,其重要性愈发凸显。随着 5G、人工智能等新兴技术的加速渗透,PCB行业面临着前所未有的挑战与机遇。产品迭代…...
从零开始打造 OpenSTLinux 6.6 Yocto 系统(基于STM32CubeMX)(九)
设备树移植 和uboot设备树修改的内容同步到kernel将设备树stm32mp157d-stm32mp157daa1-mx.dts复制到内核源码目录下 源码修改及编译 修改arch/arm/boot/dts/st/Makefile,新增设备树编译 stm32mp157f-ev1-m4-examples.dtb \stm32mp157d-stm32mp157daa1-mx.dtb修改…...
【学习笔记】深入理解Java虚拟机学习笔记——第4章 虚拟机性能监控,故障处理工具
第2章 虚拟机性能监控,故障处理工具 4.1 概述 略 4.2 基础故障处理工具 4.2.1 jps:虚拟机进程状况工具 命令:jps [options] [hostid] 功能:本地虚拟机进程显示进程ID(与ps相同),可同时显示主类&#x…...
R语言速释制剂QBD解决方案之三
本文是《Quality by Design for ANDAs: An Example for Immediate-Release Dosage Forms》第一个处方的R语言解决方案。 第一个处方研究评估原料药粒径分布、MCC/Lactose比例、崩解剂用量对制剂CQAs的影响。 第二处方研究用于理解颗粒外加硬脂酸镁和滑石粉对片剂质量和可生产…...
基于Java+MySQL实现(GUI)客户管理系统
客户资料管理系统的设计与实现 第一章 需求分析 1.1 需求总体介绍 本项目为了方便维护客户信息为了方便维护客户信息,对客户进行统一管理,可以把所有客户信息录入系统,进行维护和统计功能。可通过文件的方式保存相关录入数据,对…...
Golang——7、包与接口详解
包与接口详解 1、Golang包详解1.1、Golang中包的定义和介绍1.2、Golang包管理工具go mod1.3、Golang中自定义包1.4、Golang中使用第三包1.5、init函数 2、接口详解2.1、接口的定义2.2、空接口2.3、类型断言2.4、结构体值接收者和指针接收者实现接口的区别2.5、一个结构体实现多…...
Axure 下拉框联动
实现选省、选完省之后选对应省份下的市区...
向量几何的二元性:叉乘模长与内积投影的深层联系
在数学与物理的空间世界中,向量运算构成了理解几何结构的基石。叉乘(外积)与点积(内积)作为向量代数的两大支柱,表面上呈现出截然不同的几何意义与代数形式,却在深层次上揭示了向量间相互作用的…...
