【JavaEE】多线程 -- 死锁问题

news2024/9/23 23:30:50

目录

1. 问题引入

2.死锁问题的概念和原因

 3. 解决死锁问题


1. 问题引入

在学习死锁之前, 我们先观察下面的代码能否输出正确的结果:

运行程序, 能正常输出结果:

这个代码只管上看起来, 好像是有锁冲突的, 此时的 locker 对象已经是加锁的状态, 在尝试对 locker 加锁, 不应该会出现阻塞问题吗?

其实, 问题的关键是,这两次加锁, 其实是在同一个线程上进行的.  由于是同一个线程, 此时锁对象就知道了第二次加锁的线程,  第二次加锁操作就可以直接放行通过, 不会出现阻塞.  这个特性称为 "可重入". 

使用可重入锁, 可以避免代码出现死锁问题, 如果使用的不是可重入锁, 就会出现死锁问题.

2.死锁问题的概念和原因

Java多线程中的死锁问题是指两个或多个线程互相持有对方所需的资源而无法继续执行的情况。这种情况下,线程无法释放已经占有的资源,也无法获取自己所需的资源,导致程序无法继续执行下去。

通常,发生死锁问题需要满足以下四个条件:

  1. 互斥条件(Mutual exclusion):至少有一个资源同时只能被一个线程占用。
  2. 请求与保持条件(Hold and wait):线程至少已经占有一个资源,并且正在请求另一个被其他线程占用的资源。
  3. 不可剥夺条件(No preemption):已经分配给一个线程的资源不能被强制剥夺。
  4. 循环等待条件(Circular wait):存在一个线程链,每个线程都在等待下一个线程所占有的资源。

死锁的例子:

线程1获取到锁A, 线程2获取到锁B, 接下来, 线程1尝试获取锁 B, 线程2尝试获取锁A, 此时出现了死锁问题:  

package thread;

public class ThreadDemo22 {
    public static void main(String[] args) {
        Object A = new Object();
        Object B = new Object();
        Thread t1 = new Thread(()-> {
           synchronized (A) {
               // sleep 是为了t2时间, 让t2也能拿到 B
               try {
                   Thread.sleep(1000);
               }catch (InterruptedException e) {
                   e.printStackTrace();
               }

               //尝试获取B, 并没有释放 A
               synchronized (B) {
                   System.out.println("t1拿到了两把锁");
               }
           }
        });

        Thread t2 = new Thread(()->{
            synchronized (B) {
                // sleep 是给t1时间, 让t1能拿到 A
                try {
                    Thread.sleep(1000);
                }catch (InterruptedException e) {
                    e.printStackTrace();
                }

                //尝试获取A, 并没有释放 B
                synchronized (A) {
                    System.out.println("t2拿到了两把锁");
                }
            }
        });

        t1.start();
        t2.start();
    }
}

 程序没有任何输出结果:

 3. 解决死锁问题

为了避免死锁问题,可以采取以下策略:

  1. 避免使用多个锁:尽量减少使用多个锁,如果必须使用多个锁,确保获取锁的顺序是一致的,以减少死锁的可能性。
  2. 加锁顺序:多个线程获取锁的顺序要保持一致,避免出现循环等待条件。
  3. 加锁时限:在获取锁的时候设置超时时间,如果一段时间内没有获取到锁,就放弃当前的操作,释放已经持有的锁,避免长时间等待导致死锁。
  4. 死锁检测:通过监控线程的状态和资源的使用情况,及时检测并解决潜在的死锁问题。

对于死锁例子, 我们可以使两个线程的取锁顺序保持一致:

package thread;

public class ThreadDemo22 {
    public static void main(String[] args) {
        Object A = new Object();
        Object B = new Object();
        Thread t1 = new Thread(()-> {
           synchronized (A) {
               // sleep 是为了t2时间, 让t2也能拿到 B
               try {
                   Thread.sleep(1000);
               }catch (InterruptedException e) {
                   e.printStackTrace();
               }

               //尝试获取B, 并没有释放 A
               synchronized (B) {
                   System.out.println("t1拿到了两把锁");
               }
           }
        });

        Thread t2 = new Thread(()->{
            synchronized (A) {
                // sleep 是给t1时间, 让t1能拿到 A
                try {
                    Thread.sleep(1000);
                }catch (InterruptedException e) {
                    e.printStackTrace();
                }

                //尝试获取A, 并没有释放 B
                synchronized (B) {
                    System.out.println("t2拿到了两把锁");
                }
            }
        });

        t1.start();
        t2.start();
    }
}

 

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

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

相关文章

DCAMnet网络复现与讲解

距论文阅读完毕已经过了整整一周多。。。终于抽出时间来写这篇辣!~ 论文阅读笔记放这里: 基于可变形卷积和注意力机制的带钢表面缺陷快速检测网络DCAM-Net(论文阅读笔记)-CSDN博客 为了方便观看,我把结构图也拿过来了。…

java+springboot物流管理系统设计与实现wl-ssmj+jsp

物流管理系统的开发和综合性的物流信息网站平台的建设。研究的重点是运输管理信息系统.本系统是一套基于运输作业流程的管理系统,该系统以运输任务、货品、商务三大线索设计开发。运输任务是该管理系统的核心,系统通过对运输任务中的接收、调…

智能优化算法应用:基于树种算法无线传感器网络(WSN)覆盖优化 - 附代码

智能优化算法应用:基于树种算法无线传感器网络(WSN)覆盖优化 - 附代码 文章目录 智能优化算法应用:基于树种算法无线传感器网络(WSN)覆盖优化 - 附代码1.无线传感网络节点模型2.覆盖数学模型及分析3.树种算法4.实验参数设定5.算法结果6.参考文献7.MATLAB…

渗透测试|HW蓝队

公众号:老油条运维 记录某个对某个钓鱼事件中获取的钓鱼样本进行分析,以及简单的制作学习 样本行为分析 首先看到是 qq 邮箱发来的某个压缩包大概本身是带密码的,反手就丢到虚拟机先看下大概文件,解压后是这样的一个快捷方式 然…

[iOS开发]UITableView的性能优化

一些基础的优化 (一)CPU 1. 用轻量级对象 比如用不到事件处理的地方,可以考虑使用 CALayer 取代 UIView CALayer * imageLayer [CALayer layer]; imageLayer.bounds CGRectMake(0,0,200,100); imageLayer.position CGPointMake(200,200…

windows文件删除权限

一、普通文件 这里指的是所有可以被随意删除的文件。 二、可更改权限的文件 如果想要删除的文件无法被删除,那大概是权限不够,这时候:鼠标右键、属性、安全、编辑、选择相应的组或用户(如果不知道哪个可以全选,反正…

MMdetection3.0 问题

MMdetection3.0 问题 希望各位路过的大佬指教一下: 问题: 1、NWPU-VHR-10有标注的数据一共650张,我将其分为了455张训练集,195张验证集。 2、然后使用MMdetection3.0框架中的Faster-rcnn网络进行训练,设置训练参数b…

【vue实战项目】通用管理系统:信息列表,信息录入

本文为博主的vue实战小项目系列中的第六篇,很适合后端或者才入门的小伙伴看,一个前端项目从0到1的保姆级教学。前面的内容: 【vue实战项目】通用管理系统:登录页-CSDN博客 【vue实战项目】通用管理系统:封装token操作…

Python的换行和转义:深入理解代码排版与字符串处理

更多Python学习内容:ipengtao.com 大家好,我是涛哥,今天为大家分享 Python的换行和转义:深入理解代码排版与字符串处理,全文2700字,阅读大约8分钟。 在Python编程中,正确使用换行和转义字符是保…

spring框架的事务传播级别经典篇

一 spring事务传播级别 1.1 总结概述 方法A:外围方法,方法B:内部方法,在A中调用B 1.事务级别PROPAGATION_REQUIRED: 如果A为PROPAGATION_REQUIRED:B 不管有没有设置事务级别,都会加入到A的事务级别中。如…

ssm+vue的仓库在线管理系统的设计与实现(有报告)。Javaee项目,ssm vue前后端分离项目。

演示视频: ssmvue的仓库在线管理系统的设计与实现(有报告)。Javaee项目,ssm vue前后端分离项目。 项目介绍: 采用M(model)V(view)C(controller)三…

5、DMA Demo(STM32F407)

DMA简介 DMA 全称Direct Memory Access,即直接存储器访问。 DMA传输将数据从一个地址空间复制到另一个地址空间。当CPU初始化这个传输动作,传输动作本身是由DMA控制器来实现和完成的。 DMA传输方式无需CPU直接控制传输,也没有中断处理方式那…

倒计时(JS计时器)

<script>function countDown() {document.body.innerHTML ;//清空页面内容var nowTimer new Date(); //现在时间的毫秒数var valueTimer new Date("2024-1-1 12:00"); //用户输入年份倒计时时间毫秒数var timer (valueTimer - nowTimer) / 1000; //倒计时秒…

网工内推 | 云计算运维,云相关认证优先,最高30K,带薪年假

01 安畅网络 招聘岗位&#xff1a;云计算运维工程师 职责描述&#xff1a; 1、负责对公有云平台的计算、存储、网络资源等IAAS/SAAS/PAAS层产品组件日常交付部署运维工作&#xff0c;包括调试、配置、维护、监控、优化等工作&#xff1b; 2、负责对操作系统及应用日常运行维护…

springboot+jsp+java人才招聘网站4f21r

本基于springboot的人才招聘网站主要满足3种类型用户的需求&#xff0c;这3种类型用户分别为求职者、企业和管理员&#xff0c;他们分别实现的功能如下。 &#xff08;1&#xff09;求职者进入网站后可查看职位信息、企业信息以及职位新闻等&#xff0c;注册登录后可实现申请职…

获取焦点后,样式异常的处理方法

问题 在使用monaco-editor 设置代码提示未正常显示&#xff0c;提示框出现&#xff0c;看不到内容&#xff0c;如图 看不到内容&#xff0c;有两种情况&#xff1a; 情况一&#xff1a;没有得到数据&#xff0c;所以没有展示&#xff1b; 情况二&#xff1a;得到了数据&#x…

用户注册这样玩,保你平安

前言 基本上每个系统系统都包含用户注册、发送验证码等基本操作。在前些年&#xff0c;我还记得我在逛 csdn、贴吧、网易新闻等网站的时候是可以不登陆也能浏览完网页内容的&#xff0c;但是近几年这些网站已经改成了不登陆不让用&#xff0c;浏览网页时不时提醒你要进行登录&…

基于B/S架构的医院一体化电子病历编辑器源码

电子病历在线制作、管理和使用的一体化电子病历解决方案&#xff0c;通过一体化的设计&#xff0c;提供对住院病人的电子病历书写、保存、修改、打印等功能。电子病历系统将临床医护需要的诊疗资料以符合临床思维的方法展示。建立以病人为中心&#xff0c;以临床诊疗信息为主线…

【前端开发】Next.js与Nest.js之间的差异2023

在快节奏的网络开发领域&#xff0c;JavaScript已成为构建可靠且引人入胜的在线应用程序的标准语言。然而&#xff0c;随着对适应性强、高效的在线服务的需求不断增加&#xff0c;开发人员通常不得不从广泛的库和框架中进行选择&#xff0c;以满足其项目的要求。Next.js和Nest.…

Electron+Ts+Vue+Vite桌面应用系列:TypeScript常用语法详解

文章目录 1️⃣ TypeScript常用讲解1.1 使用1.2 字符串1.3 数字1.3 布尔1.4 数组1.5 元组1.6 枚举1.7 any1.8 void1.9 object1.10 函数指定返回值的类型1.11 联合类型1.12 类型断言1.13 接口1.14 函数类型1.15 类类型1.16 泛型 2️⃣ 类2.1 类的基本写法2.2 类的继承2.3 类的修…