当前位置: 首页 > news >正文

每日三道面试题之 Java并发编程 (四)

1.什么是线程死锁

线程死锁是并发编程中一个常见问题,它发生在两个或多个线程永久性地阻塞彼此,等待对方释放锁,但没有任何一方先行释放锁的情况下。简单来说,每个线程都持有对方需要的资源而等待对方释放资源,导致所有相关线程都无法继续执行下去。

线程死锁通常涉及以下四个必要条件,这四个条件同时满足时,死锁就可能发生:

  1. 互斥条件:资源不能被多个线程同时共享,只能由一个线程在任一时刻使用。
  2. 至少有一个线程它必须持有一个资源且正在等待获取一个当前被其他线程持有的资源:即线程已经持有至少一个资源,但又试图获取另一个被其他线程持有的资源。
  3. 资源不能被线程(主动)抢占:线程已经获取的资源在未使用完之前,不能被其他线程强行抢占。
  4. 循环等待条件:发生死锁时,必然存在一个线程—资源的循环等待链,每个线程持有一个资源并等待下一个线程所持有的资源。

解决或避免死锁的方法通常包括:

  • 破坏互斥条件:虽然对于某些资源(如打印机),这几乎不可能实现,但对于软件资源来说,可以通过允许某种程度的共享来实现。
  • 破坏占有和等待条件:一种方法是要求线程一开始就请求所有必需资源,并且只有当所有请求都能被同时满足时,才分配给该线程。
  • 破坏不可抢占条件:如果某线程获得了一部分资源但请求其他资源时被拒绝,那么它必须释放已占有的资源,稍后再重新尝试。
  • 破坏循环等待条件:对所有资源进行排序,强制每个线程按顺序请求资源,这样就不会形成循环等待。

避免死锁的关键是对资源的访问进行仔细的控制和调度,以确保上述条件不会同时满足。

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

形成死锁的四个必要条件通常被称为死锁的四个基本条件,它们是:

  1. 互斥条件(Mutual Exclusion):资源不能被共享,只能由一个线程(或进程)在任一时刻使用。即在一段时间内某资源仅为一个线程所占用。如果此时还有其他线程请求该资源,则请求者只能等待,直到占有资源的线程释放该资源。

  2. 占有且等待条件(Hold and Wait):一个线程(或进程)至少保持一个资源,并且等待获取额外的资源,而这些额外的资源又被其他线程占有。线程因请求资源而阻塞时,对已获得的资源保持不放。

  3. 非抢占条件(No Preemption):资源不能被强行从一个线程(或进程)中夺走,线程(或进程)必须自愿释放资源。即一旦某线程已经获得了某资源,在未使用完之前,不能强行剥夺其资源。

  4. 循环等待条件(Circular Wait):存在一种线程(或进程)的等待循环,每个线程(或进程)都在等待下一个线程(或进程)所占有的资源。即在发生死锁时,必然存在一个线程—资源的环形链,链中的每一个线程(或进程)至少已经占有一个资源,又在等待获取下一个线程(或进程)已经占有的资源。

只有当这四个条件同时成立时,才会发生死锁。理解这些条件有助于在设计和开发软件时采取相应的预防和避免策略,从而减少或消除死锁的可能性。

3.如何避免线程死锁

避免线程死锁是多线程程序设计中的一个关键考虑点。虽然彻底避免死锁可能很困难,但以下策略可以显著减少发生死锁的风险:

  1. 避免一些必要条件

    • 互斥:对于一些资源(如打印机),互斥是必须的,但对于可共享的资源(如只读数据),可以通过允许多个线程共享资源来避免互斥。
    • 持有并等待:要求线程在开始执行前请求所有必需的资源,并且只有当所有资源都可以被同时分配时,线程才能开始执行。这样做可以减少死锁,但可能会降低资源的利用率。
    • 不可抢占:如果一个线程已经持有一些资源但请求其他资源失败,可以让它释放所有已持有的资源,从而允许其他线程使用它们,然后重新尝试。
    • 循环等待:通过定义所有资源的线性顺序,并强制所有线程按此顺序请求资源,可以破坏循环等待条件。
  2. 使用锁超时

    • 在尝试获取锁时使用超时机制是一种避免死锁的实用方法。如果线程在指定时间内无法获取所有必需的锁,它会自动释放已经获取的锁并重新尝试。这种方法增加了死锁解除的可能性,但可能会引入性能问题。
  3. 死锁检测与恢复

    • 虽然这不是预防死锁的方法,但通过定期检查死锁的存在,并采取措施(如回滚某些操作或强制释放一些资源)来打破死锁,也是处理死锁问题的一种方式。
  4. 使用顺序锁定

    • 一种避免死锁的简单方法是在程序中对所有需要锁定的资源进行排序,并确保每个线程按照这一确定的顺序获取锁。这样做可以有效避免循环等待的条件。
  5. 减少锁的粒度

    • 使用更细粒度的锁或其他同步机制(如并发数据结构),可以减少锁的争用,从而减少死锁的可能性。但这也可能增加编程的复杂性。
  6. 使用非阻塞同步机制

    • 采用非阻塞的数据结构和算法,如使用原子变量和无锁编程技术,可以完全避免死锁。这些技术通过消除传统的锁机制,来确保线程间的同步。

通过综合应用以上策略,可以大大降低多线程应用程序发生死锁的风险。然而,完全避免死锁通常需要仔细的设计和深思熟虑的资源管理策略。

相关文章:

每日三道面试题之 Java并发编程 (四)

1.什么是线程死锁 线程死锁是并发编程中一个常见问题,它发生在两个或多个线程永久性地阻塞彼此,等待对方释放锁,但没有任何一方先行释放锁的情况下。简单来说,每个线程都持有对方需要的资源而等待对方释放资源,导致所…...

ubuntu20.04.6将虚拟机用户目录映射为磁盘Z

文章目录 linux虚拟机设置为NAT模式安装sshd服务映射目录到windows磁盘安装samba套件修改配置文件smb.conf重启smbd并设置用户名和密码 windows映射遇到的问题1、设置好之后映射不成功2、smbd下载失败3、smbd密码配置问题4、当有改动时候,最好重启一下smbd服务 linu…...

TCP挥手中TIME_WAIT存在的原因

四次挥手的一般过程如图所示: 在客户端收到FIN结束报文的时候不是立刻进入CLOSED状态,而是进入TIME_WAIT状态,一般等2MLS后进入关闭状态。 原因: 1.可靠地终止 TCP 连接。 2.保证让迟来的 TCP报文段有足够的时间被识别并丢弃。 …...

使用Docker部署jar包

vi DockerfileDockerfile内容 FROM java:8 ADD chery5G-admin.jar chery5G-admin.jar ENTRYPOINT ["java","-jar","chery5G-admin.jar"]上传jar包到Dockerfile文件同级目录 使用Dockerfile文件,将jar包制作为镜像 docker build -t…...

深入了解WebKit:结构简介

随着互联网的发展,网页浏览器已经成为我们日常生活中不可或缺的工具之一。而在众多浏览器中,WebKit引擎作为其中之一的重要角色,驱动着一系列流行的浏览器,例如Safari和一些移动端浏览器。那么,WebKit究竟是如何构建的…...

Pgsql怎样找到表中某个字段值重复的记录并删除冗余记录,只保留一条

背景 今天发现某个黄页爬取的数据有部分重复了,原本我用的公司详情页的url进行md5来作为主键做upsert入,但后面在核验数据时发现有些详情url虽是同一间公司的,但路由上有细微差别导致写入了重复的公司数据,所以要想办法清理掉重复…...

如何在HarmonyOS(鸿蒙操作系统)上进行应用开发

文章中提到的关键点包括: 学习ArkTS:作者建议初学者首先学习使用ArkTS编写Hello World程序,并可以通过TypeScript教程来快速掌握基础语法。对于有Flutter或React Native开发经验的开发者来说,页面布局会比较容易上手。 页面布局&…...

C++ typeid运算符介绍

在 C++ 中,typeid() 是一个运算符,用于获取表达式的类型信息。typeid() 运算符在 C++ 中是一个强大的工具,可以用于获取对象的类型信息、类型比较、多态类型判断、异常处理以及类型转换安全检查等场景中。 1. 类型比较: 可以使用 typeid() 来比较两个类型是否相同。 if …...

Android适配平板屏幕尺寸

一、划分手机和平板 人为判断方法: 大于6英寸的就是平板。小于6英寸的都是手机 平板尺寸: 6英寸、7英寸、10英寸、14英寸… Android系统支持多配置资源文件,我们可以追加新的资源目录到你的Android项目中。命名规范: 资源名字-限制符 l…...

汽车充电桩主板在出厂前需要做哪些检测?

充电桩主板作为核心组件承载着充电桩的关键功能,其性能和稳定性直接影响着用户充电体验、桩企产品合规和市场竞争力,以及主板厂商的品牌知名度。因此,对充电桩主板进行全面的测试尤为重要。 下面将详细介绍充电桩主板检测的内容,包…...

关于Renesas R7 的选项字节开关看门狗

Renesas看门狗的模式是在选项字节中进行配置的,OPBT0的寄存器说明如下, 关于看门狗模式 : 和看门狗喂狗方式: 我们选择关闭看门狗(也就是配置31位为软件触发看门狗开始,然后不启动就相当于关闭&#xff09…...

redis bigKey问题

bigKey的产生 1、使用String存储了大文件的二进制。 2、使用集合没有考虑到数据的规模,或者规模的增长。 3、哈希中冗余了大量键值对。 bigKey问题 1、操作大key时会阻塞线程:redis是单线程。 2、网络阻塞:在网络中占用大量网络流量。 …...

二手车商的套路

https://www.dongchedi.com/article/7126394624675578405 https://www.dongchedi.com/article/7126394624675578405 现在,有越来越多的人去了解二手车,二手车相对于新车来说,更加的亲民划算。很多新车需要四五十万,而二手车有可…...

c++ 根据ip主机号和子网掩码随机生成ip

在C中&#xff0c;可以使用以下方法根据给定的IP地址和子网掩码来随机生成IP地址。这里使用了库来生成随机数&#xff0c;以及<arpa/inet.h>库来处理IP地址。 #include <iostream> #include <random> #include <arpa/inet.h>std::string random_ip(co…...

事务的隔离级别

事务由哪些特性 原子性&#xff08;Atomicity&#xff09;&#xff1a;一个事务中的所有操作&#xff0c;要么全部完成&#xff0c;要么全部不完成&#xff0c;不会结束在中间某个环节&#xff0c;而且事务在执行过程中发生错误&#xff0c;会被回滚到事务开始前的状态&#xf…...

性能优化角度

1.启动角度 2.数据缓存角度比如历史信息联想 3.内存释放角度 4.配合并要求后端进行接口API整合 5.耗时较多需求&#xff0c;根据业务情况进行线程异步处理 6.通过开源的loop监控sdk日志埋点&#xff0c;可监控线程对应环路的休眠/唤醒时间间隔&#xff0c;优化卡顿 7.尽量避免离…...

Vue3 使用ElementUI 显示异常

element提供的样例不能正常显示,需要进行配置 1.npm install element-plus --save 2.main.js // main.ts import { createApp } from vue import ElementPlus from element-plus //全局引入 import element-plus/dist/index.css import App from ./App.vue const app = crea…...

从0开始复习python~

//&#xff0c;int() , abs(), divmod() ,float() ,complex() ,pow(), ** , bool() ,or , and , len() , range() , str() , 其中 for i in xxx: else: xxxxx; 有点意思... # 地板除&#xff0c;向下取整 print(-3//2) # 只保留整数部分 print(int(3.72)) # 绝对值 print…...

从零开始搭建后端信息管理系统(新手小白比如)

如果你是新手小白&#xff0c;首先我们要进行一些准备工作&#xff0c;安装一些基础软件&#xff0c; 备注一下&#xff1a;这里安装的vue环境的后台管理系统&#xff0c;不同的后台管理系统&#xff0c;需要安装不同的插件 准备工作&#xff1a; 安装 Visual Studio Code …...

CentOS 7详细介绍。

CentOS 7是CentOS项目发布的开源类服务器操作系统&#xff0c;自2014年7月7日正式发布以来&#xff0c;它已成为企业级Linux发行版本的佼佼者。CentOS 7不仅继承了其前身的优势&#xff0c;还在性能、安全性和易用性方面进行了显著的提升。以下是对CentOS 7的详细介绍。 一、C…...

Linux链表操作全解析

Linux C语言链表深度解析与实战技巧 一、链表基础概念与内核链表优势1.1 为什么使用链表&#xff1f;1.2 Linux 内核链表与用户态链表的区别 二、内核链表结构与宏解析常用宏/函数 三、内核链表的优点四、用户态链表示例五、双向循环链表在内核中的实现优势5.1 插入效率5.2 安全…...

【Go】3、Go语言进阶与依赖管理

前言 本系列文章参考自稀土掘金上的 【字节内部课】公开课&#xff0c;做自我学习总结整理。 Go语言并发编程 Go语言原生支持并发编程&#xff0c;它的核心机制是 Goroutine 协程、Channel 通道&#xff0c;并基于CSP&#xff08;Communicating Sequential Processes&#xff0…...

MySQL 8.0 OCP 英文题库解析(十三)

Oracle 为庆祝 MySQL 30 周年&#xff0c;截止到 2025.07.31 之前。所有人均可以免费考取原价245美元的MySQL OCP 认证。 从今天开始&#xff0c;将英文题库免费公布出来&#xff0c;并进行解析&#xff0c;帮助大家在一个月之内轻松通过OCP认证。 本期公布试题111~120 试题1…...

docker 部署发现spring.profiles.active 问题

报错&#xff1a; org.springframework.boot.context.config.InvalidConfigDataPropertyException: Property spring.profiles.active imported from location class path resource [application-test.yml] is invalid in a profile specific resource [origin: class path re…...

AI,如何重构理解、匹配与决策?

AI 时代&#xff0c;我们如何理解消费&#xff1f; 作者&#xff5c;王彬 封面&#xff5c;Unplash 人们通过信息理解世界。 曾几何时&#xff0c;PC 与移动互联网重塑了人们的购物路径&#xff1a;信息变得唾手可得&#xff0c;商品决策变得高度依赖内容。 但 AI 时代的来…...

基于TurtleBot3在Gazebo地图实现机器人远程控制

1. TurtleBot3环境配置 # 下载TurtleBot3核心包 mkdir -p ~/catkin_ws/src cd ~/catkin_ws/src git clone -b noetic-devel https://github.com/ROBOTIS-GIT/turtlebot3.git git clone -b noetic https://github.com/ROBOTIS-GIT/turtlebot3_msgs.git git clone -b noetic-dev…...

算法:模拟

1.替换所有的问号 1576. 替换所有的问号 - 力扣&#xff08;LeetCode&#xff09; ​遍历字符串​&#xff1a;通过外层循环逐一检查每个字符。​遇到 ? 时处理​&#xff1a; 内层循环遍历小写字母&#xff08;a 到 z&#xff09;。对每个字母检查是否满足&#xff1a; ​与…...

uniapp手机号一键登录保姆级教程(包含前端和后端)

目录 前置条件创建uniapp项目并关联uniClound云空间开启一键登录模块并开通一键登录服务编写云函数并上传部署获取手机号流程(第一种) 前端直接调用云函数获取手机号&#xff08;第三种&#xff09;后台调用云函数获取手机号 错误码常见问题 前置条件 手机安装有sim卡手机开启…...

Qt 事件处理中 return 的深入解析

Qt 事件处理中 return 的深入解析 在 Qt 事件处理中&#xff0c;return 语句的使用是另一个关键概念&#xff0c;它与 event->accept()/event->ignore() 密切相关但作用不同。让我们详细分析一下它们之间的关系和工作原理。 核心区别&#xff1a;不同层级的事件处理 方…...

Linux中《基础IO》详细介绍

目录 理解"文件"狭义理解广义理解文件操作的归类认知系统角度文件类别 回顾C文件接口打开文件写文件读文件稍作修改&#xff0c;实现简单cat命令 输出信息到显示器&#xff0c;你有哪些方法stdin & stdout & stderr打开文件的方式 系统⽂件I/O⼀种传递标志位…...