经典面试题-死锁

目录

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把锁

哲学家进餐问题

        描述了五位哲学家围坐在一张圆桌旁,每个人面前都有一碗米饭和一只筷子。这些哲学家只能用左手和右手各拿一只筷子进食。问题是,如何安排他们的动作,使得每个哲学家都能进餐?

问题分析 :

       由问题描述我们可以知道,一共有五个哲学家,也就是五个进程;五只筷子,也就是五个临界资源;因为哲学家想要进餐,必须要同时获得左边和右边的筷子,这就是要同时进入两个临界区(使用临界资源),才可以进餐。

 问题解决:

  1. 一次只允许两个哲学家进餐,并且要求他们都拿到右手边的筷子后才能开始进食。
  2. 引入一个仲裁者,即一个额外的实体负责协调哲学家的动作,以避免死锁的发生。
  3. 使用资源分配算法,例如Dijkstra的银行家算法,来确保每个哲学家都能有足够的资源进餐。

    希望大家多多支持! 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/646552.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

windows11部署linux程序

windows11部署 msys2在windows10系统的安装 https://blog.csdn.net/engineer520/article/details/82192776 MSYS2使用记录——win10系统64位安装msys2最新版(msys2-x86_64-20190524.exe) _ https://www.cnblogs.com/world-explorer/p/16319426.html C语言…

Unity Asset store下载资源修改位置

Unity Asset Store的资源会随着项目的增长和资源的积累而越来越多。 在本文中,我们将修改Unity Asset Store的默认下载路径。 一、 默认保存路径的问题 当安装unity后,从Unity Asset Store下载资源时,它们通常会被存放在以下默认路径&#…

ThreadLocal使用

在用户每一次发起请求都会在tomcat服务器请求一个新的线程,我们在生成JWT token的时候将登录的用户信息注入到threadlocal中,那么这个线程进行其他请求都会携带着用户信息,我们可以在其他功能中得到当前的登录的用户信息,比如得到…

vue3中使用 vue3-slide-verify 滑块验证登录

在日常项目中我们实现登录的时候&#xff0c;会进行人为操作验证&#xff0c;这里使用滑块验证&#xff0c;常见的验证方式 我们借助插件 vue3-slide-verify 安装 npm install --save vue3-slide-verify 使用 在页面创建组件verification.vue 名字随意写入下面代码 <…

Linux破解密码

破解root密码&#xff08;Linux 7&#xff09; 1、先重启——e 2、Linux 16这一行 末尾加rd.break&#xff08;不要回车&#xff09;中断加载内核 3、再ctrlx启动&#xff0c;进入救援模式 4、mount -o remount&#xff0c;rw /sysroot/——&#xff08;mount挂载 o——opti…

大二下 课程安排

专业选修 web前端开发 信息与网络安全 必修 数据库原理 4 概率论与数理统计 4 软件设计与体系结构 3 编译技术 3 软件设计实践 2 大学体育 1 选修 &#xff08;待更新&#xff09; 目标 大二下一定要好好学习&#xff0c;不然最后总的排名真的就垫底了&#xff0c;大一上…

选择海外云手机需要考虑什么?

随着跨境电商行业的蓬勃发展&#xff0c;企业们纷纷寻找提升平台流量和广告投放效果的方法&#xff0c;这已成为业界的当务之急。传统的宣传模式在国内受到直播和链接带货等新兴方式的冲击&#xff0c;而在国外&#xff0c;类似的趋势也在悄然兴起&#xff0c;呈现出广阔的发展…

Halcon优化模板匹配速度

Halcon优化模板匹配速度 文章目录 Halcon优化模板匹配速度1. 缩小搜索空间2. 使用图像下采样 优化匹配速度可以从两个方面入手&#xff1a;缩小搜索空间和使用图像下采样。本节将分别从这两个方面进行解释。 1. 缩小搜索空间 搜索空间指搜索的范围&#xff0c;它是一个广义的概…

服务器运维小技巧(二)——如何进行监控告警

服务器运维难度高的原因&#xff0c;很大程度是因为服务器一旦出现问题&#xff0c;生产环境的业务就会受到严重影响&#xff0c;极有可能带来难以承担的后果。因此这份工作要求工程师保持高要求的服务质量&#xff0c;能够快速响应问题&#xff0c;及时解决问题。 但是“及时…

google-webrtc 原理

Google WebRtc Android 使用详解(包括客户端和服务端代码) - 知乎 (zhihu.com) 【记】Android使用WebRTC未释放资源导致的内存泄露 - 掘金 (juejin.cn)

Eureka-第一篇

​ 一、Eureka的概述 Eureka的基本概念和作用 Eureka是一个基于REST的服务&#xff0c;主要用于定位运行在AWS域中的中间层服务&#xff0c;以达到负载均衡和中间层服务故障转移的目的。Eureka是Netflix开发的服务发现框架&#xff0c;主要用于解决在云计算环境中动态位置服…

[docker] Docker镜像的创建以及Dockerfile的使用

一、Dokcer镜像的创建 创建镜像有三种方法&#xff0c;分别为基于已有镜像创建、基于本地模板创建以及基于Dockerfile创建。 1.1 基于现有镜像创建 &#xff08;1&#xff09;首先启动一个镜像&#xff0c;在容器里做修改docker run -it --name web centos:7 /bin/bash …

C语言应用层程序热补丁

一、热补丁简介 一个正在运行的程序&#xff0c;要是有某函数或某流程有问题&#xff0c;需要修改&#xff0c;有两个方式&#xff1a; 1.通过设置LD_PRELOAD把需要的库重新定向&#xff0c;但这种方式需要重启正在运行的程序。 2.通过修改可执行文件某个函数指向的地址&…

【C++】介绍STL中list容器的常用接口

目录 一、STL中的list简介 二、构造函数 2.1 默认构造函数 2.2 填充构造&#xff08;用n个相同的值构造&#xff09; 2.3 迭代器构造 2.4 拷贝构造和赋值运算符重载 三、迭代器 3.1 正向迭代器 3.2 反向迭代器 四、容量相关 4.1 获取list中有效数据的个数 4.2 判…

android camera的使用以及输出的图像格式

一、Camera 1.1、结合SurfaceView实现预览 1.1.1、布局 <?xml version"1.0" encoding"utf-8"?> <LinearLayout xmlns:android"http://schemas.android.com/apk/res/android"xmlns:app"http://schemas.android.com/apk/res-au…

burp靶场--CSRF

burp靶场–CSRF https://portswigger.net/web-security/csrf#what-is-csrf ### 什么是 CSRF&#xff1f; 跨站请求伪造&#xff08;也称为 CSRF&#xff09;是一种 Web 安全漏洞&#xff0c;允许攻击者诱导用户执行他们不打算执行的操作。它允许攻击者部分规避同源策略&#…

Unity 解决异步分发方案

很多程序&#xff0c;包括游戏、小程序、一些AR、VR的程序&#xff0c;因为客户端体量太大&#xff0c;更新频繁都涉及到远程热更新的问题&#xff0c;解决这类问题的思路基本上是客户端解决主要功能&#xff0c;资源类放置在服务器。 下面记录下&#xff1a; 1.CDN或者云轻量…

Windows11操作系统百科

简介 Windows 11是由微软公司&#xff08;Microsoft&#xff09;开发的操作系统&#xff0c;应用于计算机和平板电脑等设备 [1]。于2021年6月24日发布 [3]&#xff0c;2021年10月5日发行 [29]。 Windows 11提供了许多创新功能&#xff0c;增加了新版开始菜单和输入逻辑等 [6]…

安装ddddocr中遇到的问题

1、需要先安装&#xff1a; pip3 install pyinstaller --no-use-pep517 pip install scikit-build pip install setuptools pip install pyinstaller pip install pillow 重要是的是保证一个python 环境&#xff0c;多个python环境会导致各种问题。并且保证python>3.8…