【多线程进阶】死锁问题

news/2024/5/20 11:19:43 标签: 数据库, 安全, 死锁, 多线程, 哲学家问题

文章目录


前言

上文锁策略中, 当谈到可重入锁和不可重入锁时, 我们引入了一个 “死锁” 的概念, 当针对一把不可重入锁进行连续两次的加锁行为时, 就会产生死锁.

本文就重点来讲解一下关于死锁的一些知识.

关注收藏, 开始学习吧🧐


1. 什么是死锁

在锁策略中, 我们提到过死锁这一概念, 死锁是这样一种情形: 多个线程同时被阻塞, 它们中的一个或者全部都在等待某个资源被释放. 由于线程被无限期地阻塞, 因此程序不可能正常终止.

1.1 死锁的三种典型情况

1. 一个线程, 一把不可重入锁. 该线程针对这个锁连续加锁两次, 就会出现死锁.
这就是我们上文提到的锁策略中的不可重入锁, 带来的死锁, 是因为针对一把不可重入锁, 连续加锁两次所导致的.

2. 两个线程, 两把锁. 这两个线程先分别获取到一把锁, 然后再同时尝试获取对方的锁.
这个场景其实可以通过生活场景来去理解, 就好比你把车钥匙落家里了, 但是家钥匙又落车里了. 如果你想开家门, 就得先开车门. 想开车门, 就得先开家门. 无限循环形成套娃.

3. 有N个线程, 有M把锁. 这几个线程互相获取锁, 也会有几率出现死锁
很经典的 “哲学家就餐问题” 就是用来描述这个情境的.

在这里插入图片描述

  • 有一张桌子, 围着一圈 哲学家, 桌子中间放着一盘意大利面. 每个哲学家两两之间, 放着一根筷子.
  • 每个哲学家主要做两件事, 思考人生或者吃面条. 思考人生时, 会放下筷子进行思考. 准备吃面时, 会拿起左手和右手的筷子开始吃面.
  • 每个哲学家, 什么时候思考, 什么时候吃面条, 都是随机的.
  • 每个哲学家一旦准备开始吃面条, 就会非常固执的要完成吃面条的操作, 即便是此时面前筷子被别人占用, 而且等待过程中也不会放下手里已经拿着的一根筷子(拿起一根时, 发现另外一根被别人占用), 开始阻塞等待.

基于以上的设定, 在大部分情况, 这些哲学家都可以很好地开展工作, 去思考, 去吃面条. 但是如果出现了极端情况, 就会发生死锁.

假设同一时刻, 五个哲学家同时拿起左手边的筷子, 然后再尝试拿右手的筷子, 就会
发现右手的筷子都被占用了. 由于哲学家们互不相让, 这个时候就形成了死锁.

在这里插入图片描述
在哲学家就餐问题中, 五个哲学家就相当于五个线程, 五根筷子就相当于五把锁.

2. 死锁产生的必要条件

在了解死锁出现的几个典型场景后, 请思考一下, 有什么办法能够解决死锁问题呢? 想知道如何解决死锁问题, 我们首先要从根本原因出发, 先明确发生死锁的原因, 明白死锁产生的必要条件是什么.

死锁产生的四个必要条件:

  • 互斥使用, 即当资源被一个线程使用 (占有) 时, 别的线程不能使用.
  • 不可抢占, 资源请求者不能强制从资源占有者手中夺取资源, 资源只能由资源占有者主动释放.
  • 请求和保持, 即当资源请求者在请求其他的资源的同时保持对原有资源的占有.
  • 循环等待, 即存在一个等待队列: P1占有P2的资源, P2占有P3的资源, P3占有P1的资源. 这样就形成了一个等待环路.

当上述四个条件都成立的时候, 便形成死锁. 四个条件缺一不可, 只要能够破坏其中的任意一个条件, 都可以避免出现死锁. 对于我们来说, 其中最容易破坏的就是 “循环等待”.

3.如何解决死锁问题

破坏 “循环等待” 是我们解决死锁问题的关键, 而如何具体的解决死锁问题, 实际的方法有很多, 学过操作系统的读者, 应该都听说过 “银行家算法”, 该算法其实就是用来解决死锁问题的, 不过对于我们来讲, 不够接地气.

在这里, 我们介绍一个, 更加简单, 也可以高效的解决死锁问题的方法 ---- 锁排序.

锁排序就是对锁来进行编号, 并且规定好加锁的顺序, 比如约定, 每个线程如果要获取多把锁, 必须先获取编号小的锁, 后获取编号大的锁. 只要所有线程加锁都严格遵守上述规则, 那么就不会出现 “循环等待” 的这种情况.

在上述哲学家就餐问题中, 我们只要约定好, 从一到五, 给每个筷子都设置一个编号, 所有哲学家, 拿筷子时先拿编号小的筷子, 再拿编号大的筷子, 这样就不会出现我们说的那种极端情况了.


总结

✨ 本文主要讲解了一些死锁的概念, 重点介绍了死锁的几种典型场景, 以及死锁产生的几个必要条件, 并且讲述了如何去解决死锁问题.
✨ 想了解更多的多线程知识, 可以收藏一下本人的多线程学习专栏, 里面会持续更新本人的学习记录, 跟随我一起不断学习.
✨ 感谢你们的耐心阅读, 博主本人也是一名学生, 也还有需要很多学习的东西. 写这篇文章是以本人所学内容为基础, 日后也会不断更新自己的学习记录, 我们一起努力进步, 变得优秀, 小小菜鸟, 也能有大大梦想, 关注我, 一起学习.

再次感谢你们的阅读, 你们的鼓励是我创作的最大动力!!!!!


http://www.niftyadmin.cn/n/5066752.html

相关文章

插上u盘显示格式化怎么办?U盘数据恢复可以这样做

U盘以其体积小巧、存储容量大、读写速度快的特点,在各种工作和个人使用场合中得到了广泛应用,因此深得用户好评。然而,在日常使用U盘的过程中,经常会遇到一些问题和挑战。 当我需要转移一些资料文件时,总是喜欢使用U盘…

常见变量命名方法:PascalCase, camelCase, hungarian_notation, kebab-case

PascalCase 帕斯卡拼写法( 也叫大骆驼拼写法), 它主要的特点是将描述变量作用所有单词的首字母大写,然后直接连接起来,单词之间没有连接符。 比如:Age, LastName, WinterOfDiscontent camelCase (驼峰命名法)驼峰命名法第一个单…

Tensorflow、Pytorch和Ray(张量,计算图)

1.深度学习框架(Tensorflow、Pytorch) 1.1由来 可以追溯到2016年,当年最著名的事件是alphago战胜人类围棋巅峰柯洁,在那之后,学界普遍认为人工智能已经可以在一些领域超过人类,未来也必将可以在更多领域超过…

前端笔试题总结,带答案和解析(一)

1. 执行以下程序&#xff0c;输出结果为&#xff08;&#xff09; var x 10; var y 20; var z x < y ? x:y; console.log(xx;yy;zz);A x11;y21;z11 B x11;y20;z10 C x11;y21;z10 D x11;y20;z11 初始化x的值为10&#xff0c;y的值为20&#xff0c;x < y返回结果为tru…

移除元素(简单)

优质博文&#xff1a;IT-BLOG-CN 一、题目 给你一个数组nums和一个值val&#xff0c;你需要"原地"移除所有数值等于val的元素&#xff0c;并返回移除后数组的新长度。不要使用额外的数组空间&#xff0c;你必须仅使用O(1)额外空间并"原地"修改输入数组。元…

Pikachu靶场——不安全的文件下载(Unsafe Filedownload)

文章目录 1. Unsafe Filedownload1.1 Unsafe Filedownload1.1.1 源代码分析1.1.2 漏洞防御 1.2 不安全的文件下载防御措施 1. Unsafe Filedownload 不安全的文件下载概述&#xff1a; 文件下载功能在很多web系统上都会出现&#xff0c;一般我们当点击下载链接&#xff0c;便会…

接口自动化测试的概述及流程梳理~

接下来开始学习接口自动化测试。 因为之前从来没接触过&#xff0c;所以先了解一些基础知识。 1.接口测试的概述 2.接口自动化测试流程。 接口测试概述 接口&#xff0c;又叫API&#xff08;Application Programming Interface&#xff0c;应用程序编程接口&#xff09;&a…

JDBC学习笔记(2)事务

事务 在jdbc中使用使用的基本步骤&#xff1a; 调用 Connection 对象的 setAutoCommit(false) 以取消自动提交事务 在所有的 SQL 语句都成功执行后&#xff0c;调用 commit()方法提交事务 在出现异常时&#xff0c;调用 rollback()方法回滚事务 若此时 Connection 没有被关闭&…