【JAVA】:万字长篇带你了解JAVA并发编程-死锁优化【六】

目录

  • 【JAVA】:万字长篇带你了解JAVA并发编程-并发编程的优化【六】
    • 并发编程的优化
      • 避免死锁
      • 死锁产生的条件
      • 避免死锁的方式
      • 死锁例程代码
      • 使用Jps+Jstack查看进程死锁问题
    • 避免资源竞争

个人主页: 【⭐️个人主页】
需要您的【💖 点赞+关注】支持 💯

JAVA并发系列文章

  1. 【JAVA】:万字长篇带你了解JAVA并发编程【一】-CSDN博客
  2. 【JAVA】:万字长篇带你了解JAVA并发编程-线程池【二】-CSDN博客
  3. 【JAVA】:万字长篇带你了解JAVA并发编程-并发集合【三】-CSDN博客
  4. 【JAVA】:万字长篇带你了解JAVA并发编程-线程安全【四】-CSDN博客
  5. 【JAVA】:万字长篇带你了解JAVA并发编程-并发设计模式【五】-CSDN博客
  6. 【JAVA】:万字长篇带你了解JAVA并发编程-死锁优化【六】-CSDN博客

【JAVA】:万字长篇带你了解JAVA并发编程-并发编程的优化【六】

并发编程的优化

避免死锁

在多线程编程中,死锁是一个常见的问题。当多个线程同时请求多个资源,并且这些资源相互依赖于对方释放资源时,就可能发生死锁。死锁会导致程序的停滞,进而影响系统的性能和可用性。

死锁产生的条件

  • 互斥条件:进程对所分配到的资源不允许其他进程进行访问,若其他进程访问该资源,只能等待,直至占有该资源的进程使用完成后释放该资源
  • 请求和保持条件:进程获得一定的资源之后,又对其他资源发出请求,但是该资源可能被其他进程占有,此事请求阻塞,但又对自己获得的资源保持不放
  • 不可剥夺条件:是指进程已获得的资源,在未完成使用之前,不可被剥夺,只能在使用完后自己释放
  • 环路等待条件:是指进程发生死锁后,必然存在一个进程–资源之间的环形链死锁问题

避免死锁的方式

  1. 避免无谓的锁竞争

    无谓的锁竞争是指当线程获取到一个锁后,并不需要它继续保持该锁的所有权,但依然在持有锁的情况下等待其他资源的释放。这种情况下,如果其他线程也需要该锁,就可能导致死锁的发生。因此,在编写代码时,我们应该尽量避免无谓的锁竞争,只有在必要的时候才去获取和释放锁。

  2. 按顺序获取锁

    当多个线程需要获取多个锁时,为了避免死锁,我们可以约定一个获取锁的顺序,而且所有线程都按照这个顺序来获取锁。这样,即使出现了争抢资源的情况,由于按照相同的顺序获取锁,就不会发生循环等待的情况,从而避免了死锁的发生。

  3. 使用定时锁

    Java提供了一种定时锁的机制,即在尝试获取锁的时候,设定一个等待的时间,在超过这个时间之后,如果还没能获取到锁,就主动放弃锁。这样可以避免线程无限等待的情况,提高系统的可用性。

  4. 使用并发工具类

    在Java中,有很多并发工具类可以帮助我们更方便地处理多线程编程中的问题,避免死锁的发生。例如,使用ConcurrentHashMap代替Hashtable,使用ConcurrentLinkedQueue代替LinkedList等。这些并发工具类已经内部实现了线程安全的机制,可以有效地避免死锁的问题。

  5. 避免线程持有锁的时间过长

    当一个线程持有一个锁并长时间不释放时,就会阻塞其他线程的访问,并且增加了出现死锁的概率。因此,我们需要尽量缩短线程持有锁的时间,及时释放锁,以便其他线程能够及时获取锁并继续工作。

  6. 仔细设计资源申请顺序

    在设计多线程程序时,我们要仔细考虑资源申请的顺序。尽量避免一个线程同时申请多个资源,以免造成资源的竞争和死锁的发生。如果多个线程都需要获取同一组资源,可以考虑引入一个资源分配器,通过分配器来按照一定的策略来分配资源,避免资源的竞争。

  7. 使用避免死锁的算法

    在一些特殊情况下,即使遵循了以上的原则,仍然无法避免死锁的发生。这时,我们可以使用一些避免死锁的算法,例如银行家算法、资源分级算法等。这些算法可以通过动态地检测和避免死锁,保证系统的正常运行。

死锁例程代码

/*** @author 孔翔* @since 2023-11-08* copyright for author : 孔翔 at 2023-11-08* java-study*/
public class Deadlock {private static Object obj1 = new Object();private static Object obj2 = new Object();public static void main(String[] args) {new Thread(new Thread1()).start();new Thread(new Thread2()).start();}private static class Thread1 implements Runnable {@Overridepublic void run() {synchronized (obj1) {System.out.println("Thread1 拿到 obj1 的锁");try {//停顿2秒的意义在于,让thread2线程拿到obj2的锁Thread.sleep(2000);} catch (InterruptedException e) {e.printStackTrace();}synchronized (obj2) {System.out.println("Thread1 拿到 obj2 的锁");}}}}private static class Thread2 implements Runnable {@Overridepublic void run() {synchronized (obj2) {System.out.println("Thread2 拿到 obj2 的锁");try {//停顿2秒的意义在于,让thread1线程拿到obj1的锁Thread.sleep(2000);} catch (InterruptedException e) {e.printStackTrace();}synchronized (obj1) {System.out.println("Thread2 拿到 obj1 的锁");}}}}}

在这里插入图片描述
产生死锁问题

使用Jps+Jstack查看进程死锁问题

使用jps命令查看运行中的进程
在这里插入图片描述
使用jstack命令查看进程java的具体线程信息
在这里插入图片描述

总结
死锁是多线程编程中常见的问题,对系统的性能和可用性有很大的影响。为了避免死锁的发生,我们可以遵循一些原则,如避免无谓的锁竞争按顺序获取锁使用定时锁使用并发工具类等。同时,我们还需要仔细设计资源申请顺序缩短持有锁的时间,并且可以引入一些避免死锁的算法来保证系统的正常运行。通过合理地选择和应用这些方法,我们可以有效地解决死锁问题,提高系统的性能和可靠性。

避免资源竞争

资源争夺解决方案

1、互斥锁:互斥锁是最常见的资源争夺解决方案之一,它确保同一时刻只有一个线程可以访问共享资源。Java提供了synchronized关键字和ReentrantLock类来实现互斥锁。使用互斥锁可以防止多个线程同时访问共享资源,从而避免数据竞争和一致性问题。

2、信号量:信号量是一种计数器,用于控制同时访问某个资源的线程数量。Java提供了Semaphore类来实现信号量。通过调用acquire()方法获取信号量,线程可以获得对资源的访问权限。使用信号量可以灵活地控制资源的访问权限,从而解决资源争夺问题。

3、读写锁:读写锁是一种特殊的锁,用于在读多写少的场景下提高并发性能。Java提供了ReentrantReadWriteLock类来实现读写锁。读写锁允许多个线程同时读取共享资源,但只允许一个线程写入共享资源。通过使用读写锁,可以提高并发读取操作的性能,并减少争夺写操作的开销。

4、条件变量:条件变量是一种同步机制,用于在多线程环境下进行线程间通信和协调。Java提供了Condition接口和ReentrantLock类中的newCondition()方法来实现条件变量。通过使用条件变量,可以实现线程间的等待和通知机制,以解决复杂的线程协作和资源争夺问题。

5、同步集合:Java提供了许多同步集合类(如ConcurrentHashMap和ConcurrentLinkedQueue),用于在多线程环境下安全地访问和操作集合。这些同步集合类使用内部的同步机制来保证线程安全性和一致性,从而避免了手动同步和争夺资源的问题。

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

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

相关文章

C#,数值计算——偏微分方程,谱方法的微分矩阵的计算方法与源程序

1 文本格式 using System; namespace Legalsoft.Truffer { /// <summary> /// 谱方法的微分矩阵 /// Differentiation matrix for spectral methods /// </summary> public class Weights { public Weights() { …

Spring Boot项目中通过 Jasypt 对属性文件中的账号密码进行加密

下面是在Spring Boot项目中对属性文件中的账号密码进行加密的完整步骤&#xff0c;以MySQL的用户名为root&#xff0c;密码为123321为例&#xff1a; 步骤1&#xff1a;引入Jasypt依赖 在项目的pom.xml文件中&#xff0c;添加Jasypt依赖&#xff1a; <dependency><…

Go语言开发环境安装,hello world!

1. Go开发包SDK https://golang.google.cn/dl/&#xff08;国内也可以安装&#xff09; 根据自己电脑下载对应的安装包&#xff0c;我懒下载了msi安装 然后一路点确定安装Go 2.安装GoLand https://www.jetbrains.com/go/download/#sectionwindows 下载安装包 一路确定安装完…

LoRaWAN物联网架构

与其他网关一样&#xff0c;LoRaWAN网关也需要在规定的工作频率上工作。在特定国家部署网关时&#xff0c;必须要遵循LoRa联盟的区域参数。不过&#xff0c;它是没有通用频率的&#xff0c;每个国家对使用非授权MHZ频段都有不同的法律规定。例如&#xff0c;中国的LoRaWAN频段是…

接口测试工具的实验,Postman、Swagger、knife4j(黑马头条)

一、Postman 最常用的接口测试软件&#xff0c;需要注意点&#xff1a;在进行post请求时&#xff0c;需要选择JSON形式发送 输入JSON字符串&#xff0c;比如&#xff1a; {"maxBehotTime": "2021-04-19 00:19:09","minBehotTime": "2021-…

微信小程序:怎么在一个js中修改另一个js的数据(这里通过缓存进行实现)

实例&#xff1a;现有两个页面index.js和category.js,我现在想在index.js中修改category.js的数据 初始数据 category [{name: 物流配送,list: [{id: 1,job: 外卖骑手,checked: true}, {id: 2,job: 快递员,checked: false}, {id: 3,job: 司机,checked: false}, {id: 4,job: …

Nat. Med. | 基于遗传学原发部位未知癌症的分类和治疗反应预测

今天为大家介绍的是来自Alexander Gusev团队的一篇论文。原发部位未知癌症&#xff08;Cancer of unknown primary&#xff0c;CUP&#xff09;是一种无法追溯到其原发部位的癌症&#xff0c;占所有癌症的3-5&#xff05;。CUP缺乏已建立的靶向治疗方法&#xff0c;导致普遍预后…

支持存档的书签服务LinkWarden

什么是 LinkWarden &#xff1f; Linkwarden 是一个自托管、开源协作书签管理器&#xff0c;用于收集、组织和存档网页。目标是将您在网络上找到的有用网页和文章组织到一个地方&#xff0c;并且由于有用的网页可能会消失&#xff08;参见链接失效的必然性&#xff09;&#xf…

回归模型原理总结及代码实现

前言 本文将介绍回归模型算法&#xff0c;并总结了一些常用的除线性回归模型之外的模型&#xff0c;其中包括一些单模型及集成学习器。 保序回归、多项式回归、多输出回归、多输出K近邻回归、决策树回归、多输出决策树回归、AdaBoost回归、梯度提升决策树回归、人工神经网络、…

Kibana使用Timelion根据时间序列展示数据

天行健&#xff0c;君子以自强不息&#xff1b;地势坤&#xff0c;君子以厚德载物。 每个人都有惰性&#xff0c;但不断学习是好好生活的根本&#xff0c;共勉&#xff01; 文章均为学习整理笔记&#xff0c;分享记录为主&#xff0c;如有错误请指正&#xff0c;共同学习进步。…

工业自动化工厂PLC远程控制网关物联网应用

远程控制网关在工厂自动化领域中起到了至关重要的作用&#xff0c;特别是在工厂PLC数据通讯方面。它充当着数据传输的桥梁&#xff0c;连接了工厂中的各类设备和系统&#xff0c;实现了远程监控和控制的功能。本文将详细介绍远程控制网关在工厂PLC数据通讯中的应用。 远程控制网…

计算机毕业设计 基于SpringBoot的私人西服定制系统的设计与实现 Java实战项目 附源码+文档+视频讲解

博主介绍&#xff1a;✌从事软件开发10年之余&#xff0c;专注于Java技术领域、Python人工智能及数据挖掘、小程序项目开发和Android项目开发等。CSDN、掘金、华为云、InfoQ、阿里云等平台优质作者✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精…

浅谈电力物联网时代物联网技术在电力系统中的应用

贾丽丽 安科瑞电气股份有限公司 上海嘉定201801 摘要&#xff1a;在电力系统建设中&#xff0c;物联网的应用不仅促进了我国电力工业的发展&#xff0c;而且对我国的物联网技术也起到了一定的促进作用。随着物联网技术应用于电力系统&#xff0c;推动了中国工业的快速发展。因…

利用python找出偏序集中极大元、极小元、最大元和最小元

1 问题 在离散数学“关系”这一章的学习过程中&#xff0c;学到偏序集中极大元、极小元、最大元和最小元的求解方法&#xff0c;于是提出能不能用python语言实现偏序集中极大元、极小元、最大元和最小元的求解&#xff1f; 2 方法 判断偏序集中的极大元、极小元、最大元和最小元…

常见React Hooks 钩子函数用法

一、useState useState()用于为函数组件引入状态&#xff08;state&#xff09;。纯函数不能有状态&#xff0c;所以把状态放在钩子里面。 import React, { useState } from react import ./Button.cssexport function UseStateWithoutFunc() {const [name, setName] useStat…

了解高防服务器的工作原理

在当今互联网时代&#xff0c;网络安全问题日益突出&#xff0c;各种网络攻击层出不穷。为了保护企业的网络安全&#xff0c;高防服务器应运而生。那么&#xff0c;你是否了解高防服务器的工作原理呢?下面就让我们一起来探索一下。 高防服务器是一种能够有效抵御各种网络攻击的…

Bun 1.0.7 版本发布,实现多个 Node.js 兼容改进

导读Bun 是一个集打包工具、转译器和包管理器于一体的 JavaScript 运行时&#xff0c;由 Jarred Sumner 发布了 1.0.7 版本。本次更新实现了对 Node.js 运行时的多项兼容性改进&#xff0c;并修复了近 60 个 bug。 根据发布说明&#xff0c;本版本对 “bun install” 命令进行…

uview组件u-tabs添加badge数字消息提醒

效果图 在slot插槽中&#xff0c;使用v-if指令来判断当前选项卡是否是当前激活的选项卡&#xff08;即index是否等于currentTab&#xff09;&#xff0c;以及徽标数是否大于0。 <view><u-tabs:list"listTab" //标题数据:is-scroll"false":curre…

【C++初阶】一、入门知识讲解(C++关键字、命名空间、C++输入输出、缺省参数、函数重载)

相关代码gitee自取&#xff1a; C语言学习日记: 加油努力 (gitee.com) 接上期&#xff1a; 【数据结构初阶】十一、归并排序(比较排序)的讲解和实现 &#xff08;递归版本 非递归版本 -- C语言实现&#xff09;-CSDN博客 引言&#xff1a;什么是C C语言是结构化和模块化的…

pytest全局变量的使用

这里重新阐述下PageObject设计模式&#xff1a; PageObject设计模式是selenium自动化最成熟&#xff0c;最受欢迎的一种模式&#xff0c;这里用pytest同样适用 这里直接提供代码&#xff1a; 全局变量 conftest.py """ conftest.py 全局变量&#xff0c;主要实…