什么是线程死锁?形成条件是什么?如何避免?

什么是线程死锁?形成死锁的四个必要条件是什么?如何避免线程死锁? 线程死锁是指两个或多个线程由于互相持有对方所需要的资源而无法继续执行的情况。当多个线程同时占用资源,并等待其他线程释放它们所需要的资源时,可能会导致死锁。在死锁状态下,各线程都处于等待状态,无法继续执行,从而导致程序无法继续运行。 阅读详情

什么是线程死锁

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

多个线程同时被阻塞,它们中的一个或者全部都在等待某个资源被释放。由于线程被无限期地阻塞,因此程序不可能正常终止。

如下图所示,线程 A 持有资源 2,线程 B 持有资源 1,他们同时都想申请对方的资源,所以这两个线程就会互相等待而进入死锁状态。

线程死锁

下面通过一个例子来说明线程死锁,代码模拟了上图的死锁的情况 (代码来源于《并发编程之美》输出结果

public class DeadLockDemo {
    private static Object resource1 = new Object();//资源 1
    private static Object resource2 = new Object();//资源 2

    public static void main(String[] args) {
        new Thread(() -> {
            synchronized (resource1) {
                System.out.println(Thread.currentThread() + "get resource1");
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println(Thread.currentThread() + "waiting get resource2");
                synchronized (resource2) {
                    System.out.println(Thread.currentThread() + "get resource2");
                }
            }
        }, "线程 1").start();
        new Thread(() -> {
            synchronized (resource2) {
                System.out.println(Thread.currentThread() + "get resource2");
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println(Thread.currentThread() + "waiting get resource1");
                synchronized (resource1) {
                    System.out.println(Thread.currentThread() + "get resource1");
                }
            }
        }, "线程 2").start();
    }
}

输出结果

Thread[线程 1,5,main]get resource1
Thread[线程 2,5,main]get resource2
Thread[线程 1,5,main]waiting get resource2
Thread[线程 2,5,main]waiting get resource1

线程 A 通过 synchronized (resource1) 获得 resource1 的监视器锁,然后通过Thread.sleep(1000);让线程 A 休眠 1s 为的是让线程 B 得到CPU执行权,然后获取到 resource2 的监视器锁。线程 A 和线程 B 休眠结束了都开始企图请求获取对方的资源,然后这两个线程就会陷入互相等待的状态,这也就产生了死锁。上面的例子符合产生死锁的四个必要条件。

形成死锁的四个必要条件是什么

(1)互斥条件:线程(进程)对于所分配到的资源具有排它性,即一个资源只能被一个线程(进程)占用,直到被该线程(进程)释放

(2)请求与保持条件:一个线程(进程)因请求被占用资源而发生阻塞时,对已获得的资源保持不放。

(3)不剥夺条件:线程(进程)已获得的资源在末使用完之前不能被其他线程强行剥夺,只有自己使用完毕后才释放资源。

(4)循环等待条件:当发生死锁时,所等待的线程(进程)必定会形成一个环路(类似于死循环),造成永久阻塞

 

如何避免线程死锁

我们只要破坏产生死锁的四个条件中的其中一个就可以了。

破坏互斥条件

这个条件我们没有办法破坏,因为我们用锁本来就是想让他们互斥的(临界资源需要互斥访问)。

破坏请求与保持条件

一次性申请所有的资源。

破坏不剥夺条件

占用部分资源的线程进一步申请其他资源时,如果申请不到,可以主动释放它占有的资源。

破坏循环等待条件

靠按序申请资源来预防。按某一顺序申请资源,释放资源则反序释放。破坏循环等待条件。

我们对线程 2 的代码修改成下面这样就不会产生死锁了。

new Thread(() -> {
    synchronized (resource1) {
        System.out.println(Thread.currentThread() + "get resource1");
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println(Thread.currentThread() + "waiting get resource2");
        synchronized (resource2) {
            System.out.println(Thread.currentThread() + "get resource2");
        }
    }
}, "线程 2").start();

输出结果

Thread[线程 1,5,main]get resource1我们分析一下上面的代码为什么避免了死锁的发生?

我们分析一下上面的代码为什么避免了死锁的发生?

线程 1 首先获得到 resource1 的监视器锁,这时候线程 2 就获取不到了。然后线程 1 再去获取 resource2 的监视器锁,可以获取到。然后线程 1 释放了对 resource1、resource2 的监视器锁的占用,线程 2 获取到就可以执行了。这样就破坏了破坏循环等待条件,因此避免了死锁。

 

最后

欢迎关注公众号:程序员追风,领取一线大厂Java面试题总结+各知识点学习思维导图+一份300页pdf文档的Java核心知识点总结! 

基于Python实现的捕鱼达人小游戏源代码+使用说明 摘要: 本文介绍了一款自制的捕鱼达人小游戏,使用Python3和Pygame模块开发。游戏包含完整的资源文件(图片、音效、字体)和源码结构(11个功能模块),实现了大炮移动射击、特殊子弹、炸弹、难度递增等核心玩法。安装需配置Python环境和Pygame模块,运行main.py即可启动游戏。游戏支持键盘控制(方向键移动、空格射击、1键放炸弹),默认时长600秒,包含开始菜单、游戏界面和结束界面。所有代码均有详细注释,项目已开源并提供下载链接。(150字) 阅读详情

相关推荐

从零搭建ROS机械臂仿真环境:Ubuntu 20.04+Noetic下配置睿尔曼RM65的完整流程

本文详细介绍了在Ubuntu 20.04系统中,基于ROS Noetic搭建睿尔曼RM65机械臂的完整仿真环境。从环境准备、工作空间创建到MoveIt!配置与Gazebo仿真环境集成,提供了完整的流程和优化建议,帮助开发者高效实现机械臂仿真与调试。

v6b7n8m9q0的博客 933

java 线程 防止_Java中的线程死锁是什么?如何避免?

认识线程死锁多个线程同时被阻塞,它们中的一个或者全部都在等待某个资源被释放。由于线程被无限期地阻塞,因此程序不可能正常终止。如下图所示,线程 A 持有资源 2,线程 B 持有资源 1,他们同时都想申请对方的资源,所以这两个线程就会互相等待而进入死锁状态。下面通过一个例子来说明线程死锁,代码模拟了上图的死锁的情况 (代码来源于《并发编程之美》):public class DeadLockDemo {...

weixin_35569158的博客 482

解锁Cherry Studio高阶玩法:用MCP实现自动化测试与数据爬取

本文深入探讨了如何利用MCP协议与Cherry Studio结合,实现自动化测试与数据爬取的高阶应用。通过Playwright等工具的MCP集成方案,详细解析了自动化测试流水线构建和智能爬虫系统开发的关键技术,显著提升工程效率和系统适应性。

defi6farmer的博客 275

多线程之死锁详解

一、什么是死锁 当两个或两个以上的线程在执行过程中,因为争夺资源而造成的一种相互等待的状态,由于存在一种环路的锁依赖关系而永远地等待下去,如果没有外部干涉,他们将永远等待下去,此时的这个状态称之为死锁。 经典的 “哲学家进餐” 问题很好地描述了死锁状况: 5个哲学家去吃中餐,坐在一张圆桌旁,他们有5根筷子(而不是5双),并且每两个人中间放一根筷子,哲学家们要么在思考,要么 在进餐,每个人都需...

牧小农 1万+

FreeModbus V1.6主机模式实战:如何在STM32上实现Modbus RTU主从一体通信

本文详细介绍了如何在STM32平台上利用FreeModbus V1.6开源协议栈实现Modbus RTU主从一体通信。文章深入剖析了V1.6版本主机模式的架构设计,提供了从硬件配置、串口与定时器移植到FreeRTOS操作系统适配的完整实战指南,并分享了数据缓冲区管理、多线程协同及高级调试技巧,为构建稳定可靠的工业通信网关提供了系统化解决方案。

weixin_29194255的博客 374

DCA决策曲线的解读和代码实现

0.决策曲线 决策曲线分析法(Decision Curve Analysis,DCA)是个与ROC曲线相提并论的相对比较新的模型评价方法。 关于它的原理,长篇大论的医学统计学知识解读实在不是我的强项,放上两个链接偷偷懒: https://www.plob.org/article/12455.html https://www.iikx.com/news/statistics/1622.html 如果想看文章,这篇里的fig7就是:https://www.ncbi.nlm.nih.gov/pmc/artic

weixin_42960896的博客 1万+

多线程——死锁详解

死锁是指两个或两个以上的进程在执⾏过程中,由于竞争资源或者由于彼此通信⽽造成的⼀种阻塞的现象,若⽆外⼒作⽤,它们都将⽆法推进下去。(也就是两个线程拥有锁的情况下,⼜在尝试获取对⽅锁,从⽽造成程序⼀直阻塞的情况。

qq_55072036的博客 1979

8.9华为OD机试真题 新系统 - 灯带颜色变换 (Java/Py/C/C++/Js/Go)

8.9华为OD机试真题 新系统 - 灯带颜色变换 (Java/Py/C/C++/Js/Go)

算法大师! 670

线程死锁详细介绍

死锁是指两个或多个线程互相等待对方占用的资源,而永远无法继续执行下去的情形。更正式的说,死锁是在多线程环境中,多个线程因争夺系统资源而造成的一种互相等待的现象。若无外力干预,这些线程将永远处于等待状态,导致整个程序无法继续运行。

Flying_Fish_roe的博客 2073

YOLOv8改进策略【Neck】| CVPR 2024 MFM(Modulation Fusion Module,调制融合模块):动态特征加权融合,突出关键特征抑制冗余

本文主要利用DCMPNet中的 MFM 模块优化 YOLOv8 的目标检测网络模型。模块通过动态调制特征融合过程,实现了对多尺度、跨层级特征的智能聚合。将其应用于的改进过程中,针对目标检测中边界特征与语义信息的互补性需求,缓解网络中浅层细节与深层语义融合不足的问题。Depth Information Assisted Collaborative Mutual Promotion Network for Single Image Dehazing在图像去雾网络中,不同层级和类型的特征包含着互补的信息(如浅层的

Limiiiing的博客 351

【图像超分】论文复现:CVPR 2024 | 轻量化超分 | 窗口注意力改进 | CAMixerSR的Pytorch源码复现,跑通源码,获得指标和超分结果,计算复杂度,架构梳理拆解,逐行注释!

本文介绍了超分辨率重建方法CAMixerSR的代码实现与运行指南。文章亮点包括:完整跑通源码获取PSNR/SSIM指标和可视化结果;详细解析模型架构与关键代码注释,帮助快速复现基线模型。实验部分提供了测试配置文件和训练设置说明,支持2K/4K/8K大图像超分和x2/x4轻量化超分。环境依赖PyTorch和BasicSR框架,数据集包含DIV2K等常用基准。测试结果与论文指标一致,可视化输出保存至指定目录。训练配置可自定义数据集路径、GPU数量等参数。该实现突出了CAMixerSR在降低W-MSA复杂度方面的

主要更新底层视觉(去噪、超分等)相关的科研内容,形式为【论文精读】+【论文复现】 438

线程的死锁

文章目录前言一、什么是死锁?二、死锁是怎样产生的?三、怎样实现一个死锁?四、死锁的排查和预防?总结 前言 什么是死锁?死锁是怎样产生的?怎么实现一个死锁?如何解决死锁?可能我们日常工作中很少用到这些相关内容,但是随着要求越来越高,这些东西不了解是不行的,下面对死锁做一个简单的记录。 一、什么是死锁? 先看一下百度百科对死锁的定义: 死锁是指两个或两个以上的进程在执行过程中,由于竞争资源或者由于彼此通信而造成的一种阻塞的现象,若无外力作用,它们都将无法推进下去。此时称系统处于死锁状态或系统产生了死锁,这.

雅俗共赏的博客 975

SAP 批次管理(分割评估)

批次分割评估: 业务场景:企业要求各批次物料成本价格不一样。此时可以采用分割批次来实现不同成本 后台配置: (1)、激活分割评估 后台---物料管理----评估与科目设置---分割评估-----激活分割评估 (2)、配置分割评估 后台---物料管理----评估与科目设置---分割评估-----配置分割评估 进入全局性分类后,批次分割采用已有的评估类型“X自动(批)”: ...

willieyuan的博客 1万+

java多线程死锁的四个条件,什么是线程死锁?形成条件是什么?如何避免?

什么是线程死锁死锁是指两个或两个以上的进程(线程)在执行过程中,由于竞争资源或者由于彼此通信而造成的一种阻塞的现象,若无外力作用,它们都将无法推进下去。此时称系统处于死锁状态或系统产生了死锁,这些永远在互相等待的进程(线程)称为死锁进程(线程)。多个线程同时被阻塞,它们中的一个或者全部都在等待某个资源被释放。由于线程被无限期地阻塞,因此程序不可能正常终止。如下图所示,线程 A 持有资源 2,线程 ...

weixin_36130575的博客 516

VB摄像头监控

该VB模块可对摄像头捕获的画面进行录像等,可在创建的窗口进行控制

SAP B1中文培訓教材_SDK

公司内部培训资料,对开发工具 ,DIAPI, UIAPI,Add-ON有详细解说

【多线程】什么是线程死锁?形成条件是什么?如何避免?

死锁是指两个或两个以上的进程(线程)在执行过程中,由于竞争资源或者由于彼此通信而造成的一种阻塞的现象,若无外力作用,它们都将无法推进下去。此时称系统处于死锁状态或系统产生了死锁,这些永远在互相等待的进程(线程)称为死锁进程(线程)。多个线程同时被阻塞,它们中的一个或者全部都在等待某个资源被释放。由于线程被无限期地阻塞,因此程序不可能正常终止。如下图所示,线程 A 持有资源 2,线程 B 持有资源 1,他们同时都想申请对方的资源,所以这两个线程就会互相等待而进入死锁状态。

DreamSun的博客 1038

霍尼韦尔SoftMaster使用说明

霍尼韦尔SoftMaster使用说明

Java 线程死锁及如何避免死锁介绍

死锁是指两个或两个以上的线程在执行过程中,**因争夺资源而造成的互相等待**的现象,在无外力作用的情况下,这些线程会一直相互等待而无法继续运行下去,

weixin_46448719的博客 4836

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

线程死锁是什么

线程死锁:两个或两个以上的线程在执行过程中同时被阻塞,它们中的某个或者全部都在等待某个资源被释放,由于线程被无限期的阻塞,系统处于死锁状态或系统产生了死锁,这些永远在互相等待的线程被称为线程死锁 如上图所示,线程A持有资源2,线程B持有资源1,它们都想申请对方的资源,所以这两个线程就会互相等待而进入死锁状态 如果想要了解什么是线程阻塞的朋友,可以看我之前发的一篇线程的阻塞线程死锁示例代码如下: 线程 A 通过 synchronized (resource1) 获得 resource1 的监视器锁,然后通

Ai1114的博客 4万+

并发——什么是线程死锁?如何避免死锁?

然后线程 1 释放了对 resource1、resource2 的监视器锁的占用,线程 2 获取到就可以执行了。线程 A 和线程 B 休眠结束了都开始企图请求获取对方的资源,然后这两个线程就会陷入互相等待的状态,这也就产生了死锁。如下图所示,线程 A 持有资源 2,线程 B 持有资源 1,他们同时都想申请对方的资源,所以这两个线程就会互相等待而进入死锁状态。我上面说了产生死锁的四个必要条件,为了避免死锁,我们只要破坏产生死锁的四个条件中的其中一个就可以了。我们分析一下上面的代码为什么避免了死锁的发生?

帆的博客 277

请解释⼀下什么是线程死锁,以及如何避免死锁的发⽣

线程死锁是指两个或多个线程在争夺资源时,彼此形成了循环等待,导致它们都无法继续执行的现象。简单来说,线程 A 持有资源 1,并等待资源 2,而线程 B 持有资源 2,并等待资源 1。使用第三方工具或者框架对死锁进行检测,例如 Visual Studio 的调试器可以帮助发现死锁。如果在超时时间内无法获得锁,则释放当前已持有的锁,避免死锁。确保所有线程按照相同的顺序申请锁资源。避免一个线程在持有一个锁的同时再去申请另一个锁。如果满足以上四个条件,就可能发生死锁。实现超时机制,避免线程无限等待。

fapw15的博客 1646

线程死锁

死锁(DeadLock) 死锁概述 线程死锁是指两个或两个以上的线程互相持有对方所需要的资源,由于synchronized的特性,一个线程持有一个资源,或者说获得一个锁,在该线程释放这个锁之前,其它线程是获取不到这个锁的,而且会一直死等下去,因此这便造成了死锁。 死锁产生的条件 互斥条件:一个资源,或者说一个锁只能被一个线程所占用,当一个线程首先获取到这个锁之后,在该线程释放这个锁之前,其它线程...

博客 1万+

什么是死锁?自己动手写死锁。一个死锁的例子。死锁的四个条件,如何避免死锁。

文章目录一、什么是死锁二、动手写死锁三、发现排查死锁情况四、解决办法 面试题就好像计算机二级一样扯淡的出一些并不常见的题目(甚至写法很反人类),我们就借此锻炼一下逻辑能力把。 一、什么是死锁 死锁不仅在个人学习中,甚至在开发中也并不常见。但是一旦出现死锁,后果将非常严重。 首先什么是死锁呢?打个比方,就好像有两个人打架,互相限制住了(锁住,抱住)彼此一样,互相动弹不得,而且互相欧气,你不松手我就不...

白衣 5602

Java线程避免死锁_如何避免多线程死锁?多线程死锁的原因和幸免策略

在多线程编程过程中,不仅仅要解决数据访问的同步与互斥,还要注意多线程的死锁问题,而造成多线程死锁的原因大概可以归咎于系统资源不足、进程推进顺序不当或者资源分配不当等问题。有什么方法可以避免多线程死锁的形成吗?请看下文。一、死锁原因与形成条件:死锁形成的原因:1、系统资源不足;2、进程(线程)推进的顺序不恰当;3、资源分配不当。从编程经验上来讲,形成死锁的一般原因有以下几种:1、个人使用锁的经验差异...

weixin_31557179的博客 359

什么是线程死锁?如何避免死锁?看一次就明白

线程1首先获取到resource1的监视器锁,这时候线程2就获取不到了。然后线程1释放了resource1、resource2的监视器锁的占用,线程2获取到就可以执行了,这样就破坏了破坏循环等待条件,因此就避免了死锁。线程A和线程B休眠结束了都开始企图请求获取对方的资源,然后这两个线程就会陷入互相等待的状态,这也就产生了死锁。如下图所示,线程A持有资源2,线程B持有资源1,他们同时都想申请对方的资源,所以这两个线程就会互相等待而进入死锁状态。

2401_83384536的博客 415

死锁不再困扰你!Java程序员必学的死锁避坑指南

大家好!这里是你们的小米,今天又带来了一个Java社招面试题,咱们继续在技术的海洋里遨游。这次咱们来聊聊“线程死锁”这个问题,为什么死锁是一个面试中的常见考点?因为它不仅考察了你对Java线程的理解,还能看到你对多线程编程中潜在问题的预见力。好了,废话不多说,我们直接进入今天的主题——什么是线程死锁?形成死锁的四个必要条件...

cnzzs的博客 974
上一篇: 阿里面试官必问的12个MySQL数据库基础知识,哪些你还不知道?
下一篇: 95道MongoDB面试题(含答案),1万字详细解析!
程序员追风
程序员追风 优质创作者: Java技术领域 优质创作者: Java技术领域
博客等级 码龄7年 9635粉丝 237原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值