浅谈死锁以及判断死锁的方法

news2025/1/16 22:04:23

引言

我们在并发情况下见过很多种锁,synchronized,ReentrantLock 等等,这些锁是为了保证线程安全,使线程同步的锁,与今天所要学习的死锁并不相同,死锁并不是一种锁,而是一种现象。

官方定义:死锁就是在两个或两个以上线程都想获得对方所持有的资源,从而相互等待的这么一种状态。

*************************************************举个栗子*************************************************

你正在面试,面试官让你给他讲一讲什么是死锁,然后你告诉面试官:“你给我发 offer 我就讲讲什么是死锁。”面试官说:“你给我讲讲死锁,我就给你发 offer。”这就进入了互相等待的状态,面试官想获得你对死锁的理解,你又想获得面试官的 offer 这就是两个线程都想获得对方所持有的资源,从而互相等待。

代码示例

程序中有两个线程

线程 t1 需要先获得锁 lockA 再获得锁 lockB

线程 t2 需要先获得锁 lockB 再获得锁 lockA

我们可以预料的是,当 t1,t2 线程启动之后,t1 线程获得了 lockA,t2 线程获得了 lockB,这时候 t1 线程再想获得 lockB 就会进入到 blocked 状态,t2 线程想获得 lockA 也会进入到 blocked 状态,这样两个线程就会互相等待,造成死锁。

public class Demo01 {
    public static void main(String[] args) {
        DeadLock deadLock = new DeadLock();
        Thread t1 = new Thread(() -> {
            try {
                deadLock.add();
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        }, "t1线程");
        Thread t2 = new Thread(() -> {
            deadLock.dec();
        }, "t2线程");
        t1.start();
        t2.start();
    }
}

class DeadLock {
    private final Object lockA = new Object();
    private final Object lockB = new Object();

    public void add() throws InterruptedException {
        synchronized (lockA) {  // 获取lockA
            /**
             * 线程休眠
             * 为了让其他线程尽快获得lockB
             * 否则当前线程执行太快会得到lockA,lockB就不会死锁
             */
            Thread.sleep(1000);
            synchronized (lockB) { // 又获取到了lockB
                System.out.println("add()");
            }
        }
    }

    public void dec() {
        synchronized (lockB) {
            synchronized (lockA) {
                System.out.println("dec()");
            }
        }
    }
}

判断死锁

程序出现死锁之后就会,进入等待状态,不会向下运行,那么难道只要程序出现了等待这种状态就是死锁了吗?

其实不一定,我们可以使用两个命令来观测

  1. 使用 jps -l命令,显示本地所有JVM进程,查找当前JVM进程的进程号

  1. 通过jstack命令,显示当前JVM虚拟机的栈信息,查找产生死锁的线程

这就是确定程序出现死锁了

避免死锁的方式

  1. 持有的锁不要超过 1 把
  2. 按相同顺序获得锁,这样没有锁的线程就会进入 blocked 状态

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

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

相关文章

Live800:从心出发,以情动人:构建深度客户服务文化

在当今这个竞争激烈的市场环境中,企业之间的较量已不仅仅局限于产品质量的比拼,更在于谁能提供更优质、更贴心的客户服务。在这个背景下,“从心出发,以情动人”成为了构建深度客户服务文化的核心理念,它要求企业不仅要…

Nacos注册中心(Nacos安装,快速入门,多级存储,负载均衡,环境隔离,配置管理,热更新,集群搭建,nginx反向代理)

Nacos注册中心 1. Nacos安装 (windows) 1.1 官网下载 网址:https://github.com/alibaba/nacos/releases/tag/1.4.1 这里下载nacos1.4.1的Windows版本为例1.2 解压到本地 注: 解压到非中文目录 nacos默认端口号:8848,可在配置文件properties中修改1.3 启动nacos 在G:\Sp…

基于单片机的智能电话控制系统设计

摘要: 为了能够使用电话实现电器设备的控制,文中通过单片机及双音多频解码集成电路,使用用 户通过电话输入相应的指令就能够实现远程设备的智能化控制。文章主要对系统的构成、软件及 硬件设计进行了简单的介绍,并且对其中的电路…

前端vue-v-for循环遍历

(item,index)in list中,index这个索引可加可不加,item代表list中的每一个元素,list可以是数组,也可以是对象,要遍历谁就把 (item,index)in list加在哪里。 关于加不加&a…

抓机遇,促发展——2025第十二届广州国际汽车零部件加工技术及汽车模具展览会

新能源时代,电动化、智能化正在重塑全球汽车市场格局。中国自主品牌新能源汽车的市占率不断提升、头部效应初显,更有机会带动相关供应链企业成长。中国的零部件企业有望抓住变局下的机会,在新一轮竞争中崛起。 智能电动车时代,汽车…

OpenHarmony(鸿蒙南向开发)——小型系统内核(LiteOS-A)【内核通信机制】上

往期知识点记录: 鸿蒙(HarmonyOS)应用层开发(北向)知识点汇总 鸿蒙(OpenHarmony)南向开发保姆级知识点汇总~ 子系统开发内核 轻量系统内核(LiteOS-M) 轻量系统内核&#…

操作系统迁移(CentOs -> Ubuntu)

目录 1. CentOs操作系统:备份数据 1.1 gitee备份 1.1.1 CentOs安装git 1.1.1.1 运行安装命令 1.1.1.2 运行安装命令时出错 1.1.1.3 再次执行安装命令 1.1.2 gitee创建仓库 1.1.2.1 创建仓库 1.1.3 备份 1.1.3.1 复制链接 1.1.3.2 克隆仓库 1.1.3.3 备份 1.3.3.4 查…

docker学习第一步:基于Linux安装docker

要求Linux下的CentOS 7.0 以上的版本 01 安装docker版本仓库 1、设置仓库 sudo yum install -y yum-utils device-mapper-persistent-data lvm2 2、稳定仓库 sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo 02 安装及使用do…

一文看懂误植域名的威胁和对策

你熟悉“误植域名”(typosquatting)这个术语吗?这是一种域名抢注,可能会损害你的品牌和声誉。我们在这篇博文中将探讨误植域名是什么、它与域名抢注的区别,并提供如何防止这种行为的要点。另外,我们将讨论沦…

选择优质代理IP建议分享

“在互联网的广阔世界中,代理IP作为一种重要的网络工具,扮演着连接用户与目标服务器之间的桥梁角色。不同类型的代理IP适用于不同的场景和需求,因此选择合适的代理IP类型对于提高网络访问效率、保护用户隐私至关重要。” 一、代理IP类型概述 …

如何在多台Linux虚拟机上安装和配置Zookeeper集群

Zookeeper 是一个高性能的协调服务,广泛应用于分布式系统中。本文将详细介绍如何在多台Linux虚拟机上安装和配置Zookeeper集群。下面以三台服务器(node1、node2、node3)进行讲解。 前置准备: 配置多台Linux虚拟机参考:…

跨国公司决策的影响与中国IT产业的应对

跨国公司在华研发中心的调整是一个复杂的现象,它可能受到多种因素的影响,包括全球经济环境的变化、成本考量、战略重心的转移以及地缘政治因素等。IBM中国研发中心的撤出可能会对中国IT行业造成短期的就业压力,加速人才流动,并促使…

YOLOv5白皮书-第Y1周:调用官方权重进行检测

>- **🍨 本文为[🔗365天深度学习训练营](小团体~第八波) 中的学习记录博客** >- **🍖 原作者:[K同学啊](K同学啊-CSDN博客)** 一、前言 拖了好久,终于要开始目标检测系列了。自己想过好几次&#xf…

【Python机器学习】NLP信息提取——值得提取的信息

目录 提取GPS信息 提取日期 如下一些关键的定量信息值得“手写”正则表达式: GPS位置;日期;价格;数字。 和上述可以通过正则表达式轻松捕获的信息相比,其他一些重要的自然语言信息需要更复杂的模式: 问…

Linux入门学习:Linux调试器gdb使用

1. 背景 程序的发布方式有两种,debug模式和release模式,debug是添加调试信息,release是取消调试信息, Linux gcc/g出来的二进制程序,默认是release模式,要使用gdb调试,必须在源代码生成二进制程…

html+css+js网页设计 旅游 穷游10个页面

htmlcssjs网页设计 旅游 穷游10个页面 网页作品代码简单,可使用任意HTML辑软件(如:Dreamweaver、HBuilder、Vscode 、Sublime 、Webstorm、Text 、Notepad 等任意html编辑软件进行运行及修改编辑等操作)。 获取源码 1&#xff…

SpringCloud微服务消息驱动的实践指南

Spring Cloud是一个用于构建分布式系统的开发工具,通过它可以快速搭建基于微服务架构的应用,并提供了丰富的功能和解决方案。在Spring Cloud中,消息驱动是一种常见的通信模式,通过消息传递来实现不同微服务之间的数据交互。本文将…

文件上传js代码

大家好,很久没更新了,今天空了,记录一下文件上传js代码。(自己搭建的网站,演示学习一下这种漏洞,不要做违法的事情!!!) 一般文件上传的话都是奔着getshell去的,但是一般…

【Linux 20】线程控制

文章目录 🌈 一、创建线程⭐ 1. 线程创建函数⭐ 2. 创建单线程⭐ 3. 给线程传参⭐ 4. 创建多线程⭐ 5. 获取线程 ID 🌈 二、终止线程⭐1. 使用 return 终止线程⭐ 2. 使用 pthread_exit 函数终止线程⭐ 3. 使用 pthread_cancel 函数终止线程 &#x1f30…

Python中lambda表达式的使用——完整通透版

文章目录 一、前言二、 基本语法三、举个简单的例子:四、常见应用场景1. 用于排序函数sort() 方法简介lambda 表达式的作用详细解释进一步扩展总结 2、与 map、filter、reduce 等函数结合1、 map() 函数示例:将列表中的每个数字平方 2、 filter() 函数示…