死锁的成因, 和解决方案.

2024-04-13 21:28
文章标签 解决方案 死锁 成因

本文主要是介绍死锁的成因, 和解决方案.,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

死锁

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

成因

1.一个线程一把锁

一个线程,对同一个对象,重复加锁两次,如果不支持可重入,即会出现死锁现象,但是在 Java 中,synchronized 和 ReentarntLock(后面讲) 都是支持可重入的!

所以在 Java 中,也就不会出现这样的情况,但不排除在其他语言会出现这种情况。

2.两个线程两把锁

 
public static void main(String[] args) {Object knife = new Object(); //刀Object fork = new Object(); //叉Thread t1 = new Thread(() -> {synchronized (knife) {System.out.println("张三拿到刀了!");synchronized (fork) {System.out.println("张三刀和叉都拿到了!吃牛排!");}}});Thread t2 = new Thread(() -> {synchronized (fork) {System.out.println("小美拿到叉了!");synchronized (knife) {System.out.println("小美刀和叉都拿到了!吃牛排!");}}});t1.start();t2.start();
}

此时就发现,代码僵住了,其实也就是 t1 在等 t2 释放锁,而 t2 也在等 t1 释放锁,此时两个线程都无休止的阻塞等待下去了,最终导致,张三拿不到刀叉,小美也拿不到刀叉!都不吃成牛排了! 

3.多个线程多把锁

哲学家就餐问题

有一个桌子,围着一圈哲学家,每个哲学家面前放着一碗面,哲学家两两之间放一只筷子,而桌子上的哲学家只会做两件事:吃面(获取到锁,执行后续代码)或者思考人生(阻塞等待)。

当哲学家吃面的时候,就会拿起左右手的筷子(先拿左边,再拿右边),当哲学家思考人生的时候,就会放下左右手的筷子。

如果哲学家拿到两根筷子了,就会吃面,没拿到就会思考人生!

极端情况来了!如果五个哲学家同时都拿起左手边的筷子,接着每个人都去拿自己右手边的筷子,发现右边的筷子都被别人拿走了!都要等右边的哲学家把筷子放下,此时就僵住了!由于哲学家们互不相让,此时也就形成了死锁的现象。

①互斥条件:一个资源只能被一个线程占有,当这个资源被占用后其他线程就只能等待。

②不可剥夺条件:当一个线程不主动释放资源时,此资源一直被拥有线程占有。

③请求并持有条件:线程已经拥有一个资源后仍然不满足,又尝试请求新的资源。

④环路等待条件:产生死锁一定是发生了线程资源环路链。

解决

改变死锁中的任意一个或多个条件就可以解决死锁问题,其中被修改的条件只有后两个:请求并持有条件和环路等待条件。

修改请求并持有条件

:获得了一把锁之后不再去请求获取另一把锁

 

  打破循环

于哲学家吃面的问题,对每根筷子进行编号,约定好,只能先拿左右手编号小的筷子,再拿编号大的筷子。

此时这样一来,总有一个人拿不到筷子,那么上述情况,拿到编号为 4 筷子的哲学家就能拿编号为 5 筷子吃面了,吃完了放下两支筷子,接着右手边拿到 3 筷子的哲学家就拿起放下的 编号4 筷子进行吃面了,以此类推.....

本质上我们这里讲的避免死锁的方案,就是约定加锁顺序!约定顺序后,死锁的问题就解决了!也就打破了第四点的循环等待!

其实还有一种算法,银行家算法, 但实际开发中不推荐使用,比起上述讲的办法银行家算法更复杂,也更容易出错,所以更推荐上述约定顺序的方法!

 

这篇关于死锁的成因, 和解决方案.的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/901259

相关文章

部署Vue项目到服务器后404错误的原因及解决方案

《部署Vue项目到服务器后404错误的原因及解决方案》文章介绍了Vue项目部署步骤以及404错误的解决方案,部署步骤包括构建项目、上传文件、配置Web服务器、重启Nginx和访问域名,404错误通常是... 目录一、vue项目部署步骤二、404错误原因及解决方案错误场景原因分析解决方案一、Vue项目部署步骤

在MySQL执行UPDATE语句时遇到的错误1175的解决方案

《在MySQL执行UPDATE语句时遇到的错误1175的解决方案》MySQL安全更新模式(SafeUpdateMode)限制了UPDATE和DELETE操作,要求使用WHERE子句时必须基于主键或索引... mysql 中遇到的 Error Code: 1175 是由于启用了 安全更新模式(Safe Upd

Python安装时常见报错以及解决方案

《Python安装时常见报错以及解决方案》:本文主要介绍在安装Python、配置环境变量、使用pip以及运行Python脚本时常见的错误及其解决方案,文中介绍的非常详细,需要的朋友可以参考下... 目录一、安装 python 时常见报错及解决方案(一)安装包下载失败(二)权限不足二、配置环境变量时常见报错及

Java下载文件中文文件名乱码的解决方案(文件名包含很多%)

《Java下载文件中文文件名乱码的解决方案(文件名包含很多%)》Java下载文件时,文件名中文乱码问题通常是由于编码不正确导致的,使用`URLEncoder.encode(filepath,UTF-8... 目录Java下载文件中文文件名乱码问题一般情况下,大家都是这样为了解决这个问题最终解决总结Java下

Idea实现接口的方法上无法添加@Override注解的解决方案

《Idea实现接口的方法上无法添加@Override注解的解决方案》文章介绍了在IDEA中实现接口方法时无法添加@Override注解的问题及其解决方法,主要步骤包括更改项目结构中的Languagel... 目录Idea实现接China编程口的方法上无法添加@javascriptOverride注解错误原因解决方

MySql死锁怎么排查的方法实现

《MySql死锁怎么排查的方法实现》本文主要介绍了MySql死锁怎么排查的方法实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧... 目录前言一、死锁排查方法1. 查看死锁日志方法 1:启用死锁日志输出方法 2:检查 mysql 错误

C#多线程编程中导致死锁的常见陷阱和避免方法

《C#多线程编程中导致死锁的常见陷阱和避免方法》在C#多线程编程中,死锁(Deadlock)是一种常见的、令人头疼的错误,死锁通常发生在多个线程试图获取多个资源的锁时,导致相互等待对方释放资源,最终形... 目录引言1. 什么是死锁?死锁的典型条件:2. 导致死锁的常见原因2.1 锁的顺序问题错误示例:不同

MYSQL事务死锁问题排查及解决方案

《MYSQL事务死锁问题排查及解决方案》:本文主要介绍Java服务报错日志的情况,并通过一系列排查和优化措施,最终发现并解决了服务假死的问题,文中通过代码介绍的非常详细,需要的朋友可以参考下... 目录问题现象推测 1 - 客户端无错误重试配置推测 2 - 客户端超时时间过短推测 3 - mysql 版本问

Android kotlin语言实现删除文件的解决方案

《Androidkotlin语言实现删除文件的解决方案》:本文主要介绍Androidkotlin语言实现删除文件的解决方案,在项目开发过程中,尤其是需要跨平台协作的项目,那么删除用户指定的文件的... 目录一、前言二、适用环境三、模板内容1.权限申请2.Activity中的模板一、前言在项目开发过程中,尤

Linux内存泄露的原因排查和解决方案(内存管理方法)

《Linux内存泄露的原因排查和解决方案(内存管理方法)》文章主要介绍了运维团队在Linux处理LB服务内存暴涨、内存报警问题的过程,从发现问题、排查原因到制定解决方案,并从中学习了Linux内存管理... 目录一、问题二、排查过程三、解决方案四、内存管理方法1)linux内存寻址2)Linux分页机制3)