【JavaSE-线程安全问题-死锁详解】

news2024/9/9 6:19:47

🌈个人主页:努力学编程’
个人推荐
c语言从初阶到进阶
JavaEE详解
数据结构
学好数据结构,刷题刻不容缓:点击一起刷题
🌙心灵鸡汤总有人要赢,为什么不能是我呢
在这里插入图片描述

在这里插入图片描述

🌈🌈🌈死锁的概念

对于线程安全问题,我们在上一篇文章中已经提到了一些情况,比如由于多个线程针对同一个变量修改,即类似于count++的操作,可能会由于多线程抢占式执行的特性导致count的值发生异常,其实除了这种情况之外,线程安全仍有很多我们需要注意的操作,比较典型的就是死锁

🌈🌈🌈实例死锁场景

那么到底什么事死锁呢,我们直到在上述我们提到的线程安全问题中我们解决的方法之一就是可以将count++这些操作使用synchronized关键字来使用锁将其封装起来,这就构成了锁而如果你在锁的内部,又加了一重锁,那么就可能会导致死锁,

public static Object locker=new Object();
    public static void main(String[] args) {
        Thread t1=new Thread(()->{
           synchronized (locker){
               synchronized (locker){
                   System.out.println("hello Thread");
               }
           }
        });
        t1.start();
    }

在这里插入图片描述

此时线程的代码执行到锁1后,由于锁的互斥性,这里锁2就无法抢占到锁,必须等到锁1执行完毕之后,才能有机会抢占到锁,但是要想锁1释放锁,就要执行完其中的所有代码,但是代码显然在锁2处阻塞了,此时就会出现死锁问题了.
幸运的是我们运行这段代码是可以正常打印的,这是为什么呢,原来是因为,在java内部对这个死锁的状况做了一定的优化,简单来说,就是程序员大概率会写出这样的代码,为了能提高代码的执行效率,java就会对其做出判断,当前锁对象是否已经在外部使用过,使用过h会将内部锁失效,正常执行代码.

在这里插入图片描述

🌈🌈🌈死锁场景2-多个线程多把锁

假如我们现在有两个线程,两把锁,那么此时当线程1在不释放锁1的时候,同时针对锁2加锁,线程2在不释放锁2的情况下,针对锁1加锁,那么此时就会导致死锁的发生.

public class Test {
    public static Object locker1=new Object();
    public static Object locker2=new Object();
    public static void main(String[] args) {
        Thread t1=new Thread(()->{
           synchronized (locker1){
               try {
                   Thread.sleep(100);
               } catch (InterruptedException e) {
                   throw new RuntimeException(e);
               }
               synchronized (locker2){
                  System.out.println("hello Thread1");
              }
           }
        });

        Thread t2=new Thread(()->{
           synchronized (locker2){
               try {
                   Thread.sleep(100);
               } catch (InterruptedException e) {
                   throw new RuntimeException(e);
               }
               synchronized (locker1){
                   System.out.println("hello Thread2");
               }
           }
        });
        t1.start();
        t2.start();
    }

}

运行结果:

在这里插入图片描述
过程分析:

这里线程1,线程2都有可能会抢到先执行的状况,所以我们对两个线程都加sleep操作,这样就会保证两个线程都能抢到一把最外边的锁规避一个线程将两把锁都抢占的情况.实现上述的场景

此时线程1要想继续执行代码就要等到线程2释放锁2之后,才可以抢占锁2继续执行后序的代码,而对于线程2来说,要想继续执行后序的代码,就要等线程1释放锁1之后,才能针对锁1加锁然后继续完成后续的操作.所以此时就会陷入一个僵持的场面,进而导致程序陷入持续等待的场景,这也是死锁的场景,并且此时Java也无法对其作出优化操作.

在这里插入图片描述

🌈🌈🌈哲学家问题引起的死锁问题

在古代西欧时就提出了一个非常有意思的问题,哲学界问题,是这样的,一共有五个哲学家,坐在同一个桌子上吃饭,每个人的跟前都有一根筷子和一碗饭,对于哲学家来说他们一共做两件事一:吃饭,二:思考人生,如果大家同时思考人生,后面如果大家都要开始同时吃饭那么就会出现每个人都拿着一根筷子无法正常进食.

在这里插入图片描述

其实这个场景就很好的演示了关于死锁的最后一个典型案例,即一共有m把锁,n个线程,此时就可能出现上述的案例,那么如何解决这个死锁的情况呢.

这里采取的措施是这样的,我们给每一根筷子从小到大都标号,让每个哲学家都必须拿到再它面前最小标号的筷子.此时就会出现如下场景.

在这里插入图片描述
好的,此时按照我们的要求每个人必须要先拿到自己面前最小编号的筷子,所以此时就会导致最上面的人不能拿到筷子,那么此时最左边的人就会接着拿到5号筷子,吃饭,吃完后放下筷子,离开接着是左下方人又拿着4号筷子开始吃饭,吃完离开,以此类推,所有人都可以吃到饭了.

对应到线程中也是一样的,我们可以将所有的锁进行标号,并且每次让线程拿锁按照一定的顺序,这样就会巧妙的避开当前所说的死锁问题,这里就给大家说到这里.这里关于死锁可能还有一个话题就是银行家算法,这个确实是解决死锁的一种方法,但是由于实现该算法的代码很复杂,语法较难,所以我们日常开发中是不用这种算法的,大家感兴趣的话可以自己去网上看看.

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

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

相关文章

HTML基础1-文本级元素

HTML 简介 什么是 HTML? HTML (HyperText Markup Language) 是一种用于创建网页的标准标记语言。它通过使用一系列预定义的元素来描述文档的结构和外观, 您可以使用 HTML 来建立自己的 WEB 站点。 HTML 的作用 HTML 用于定义网页的结构,…

快手文生图模型-Kolors快速上手

Kolors是什么 可图(Kolors):用于真实感文本到图像合成的扩散模型的有效训练 可图,是快手开源的一个文生图模型,架构上使用了chatglm,比普通的sd模型在中文理解上要强大很多,以往sd模型的提示词理解能力往往只有两种 …

《BeanShell 在 JMeter 中的应用》总结

通过案例进行讲解 一、BeanShell 介绍 官网: http://www.BeanShell.org BeanShell 是一种完全符合 Java 语法规范的脚本语言,具有以下特点: 是一种松散类型的脚本语言,类似 JS。是用 Java 写成的小型、免费、可下载的嵌入式 Java 源代码解…

计算机毕业设计选题推荐-零食批发商仓库管理系统-Java/Python项目实战

✨作者主页:IT研究室✨ 个人简介:曾从事计算机专业培训教学,擅长Java、Python、微信小程序、Golang、安卓Android等项目实战。接项目定制开发、代码讲解、答辩教学、文档编写、降重等。 ☑文末获取源码☑ 精彩专栏推荐⬇⬇⬇ Java项目 Python…

LocalDateTime的序列化和反序列化

背景 最近定位出一个LocalDateTime序列化相关的问题,简单记录一下。本文重点介绍Jackson对LocalDateTime的序列化和反序列化,并结合Spring应用场景进行介绍。 1.LocalDateTime与字符串转换 可以通过DateTimeFormatter实现LocalDateTime与字符串的相互…

Windows远程桌面无法拷贝文件问题

场景说明 Winwdows远程桌面,相比Linux方便一点就是,同是windows连接,其中复制粘贴功能,可以在两个windows无缝切换。 但最近笔者远程一台测试windows服务器时,发现无法在服务器上复制内容到本地,也无法从…

西门子s7第三方(S7netplus)读写操作

和西门子PLC通讯需要使用S7netplus​​这个包,可以在NuGet​​上搜索下载,下载后引入命令空间using S7.Net;​​ 创建PLC对象进行连接使用Write Read进行读写操作即可不需要在发请求帧 //创建Plc对象Plc plc; //西门子设备是s7-1200//参数1 CPu类型//参…

微信小程序+JAVA实现微信支付

时隔两年再次回归 本文主要讲的是小程序实现微信支付功能,后台采用JAVA。 一.准备工作 1.小程序 2.微信商户号 1.商户号申请 这里对小程序的申请不做赘述。 如果没有微信商户号的同学,点击该链接https://pay.weixin.qq.com/,按照下属步骤…

低代码与人工智能的融合:加速应用开发的未来趋势

什么是低代码,它是如何工作的? 低代码是一种软件开发概念,它通过最小化手工编码的方式,为开发和部署定制化应用提速。低代码平台具备模型驱动、沙盒多环境、可编程的可视化开发方式等,能用于开发包含有用户界面、业务逻…

二叉树——链式结构的实现

首先是分为三个文件进行实现:tree.h、tree.c、test.c tree.h 用链表来表示⼀棵⼆叉树,即用链来指示元素的逻辑关系。通常的方法是链表中每个结点由三个域组成,数据域和左右指针域,左右指针分别用来给出该结点左孩⼦和右孩⼦所在…

基于Springboot + vue + mysql 校友社交管理系统 设计实现

目录 📚 前言 📑摘要 1.1 研究背景 📑操作流程 📚 系统架构设计 📚 数据库设计 💬 E-R表 4.2.2数据库逻辑结构设计 📚 系统功能的具体实现 系统功能模块 系统首页 校友会信息 校友活动 …

仿RabbitMQ实现消息队列———整体框架

目录 一、项目简介 需求分析 AMQP 特点: AMQP 模型: 交换机类型 持久化 网络通信 二、服务端模块 1、交换机数据管理 2、队列数据管理 3、绑定数据管理 4、消息数据管理 5、虚拟机数据管理 6、路由匹配管理 7、消费者管理 8、信道管理 …

智源发布三款BGE新模型,再次刷新向量检索最佳水平

近期,以大语言模型(LLM)为基础的向量模型(embedding model)变得愈发流行。得益于大语言模型强大的语义理解能力,相关模型在下游任务中的检索精度得到了显著的提升。然而,当前基于大模型的向量模…

leetcode 1555 银行账号概要(postgresql)

需求 用户表: Users --------------------- | Column Name | Type | --------------------- | user_id | int | | user_name | varchar | | credit | int | --------------------- user_id 是这个表的主键。 表中的每一列包含每一个用户当前的额度信息。 交易表&…

Nginx反向代理实战

使用反向代理代理服务 假设我们有三台服务器提供不同的服务 nginx作为代理服务器 代理服务器: 192.168.101.23 其余三台服务器 服务器1 192.168.101.18 服务器2 192.168.101.87 服务器3 192.168.101.20 代理服务器的nginix配置 server {listen 8085;ser…

【机器学习基础】机器学习概述与实践基础

【作者主页】Francek Chen 【专栏介绍】 ⌈ ⌈ ⌈Python机器学习 ⌋ ⌋ ⌋ 机器学习是一门人工智能的分支学科,通过算法和模型让计算机从数据中学习,进行模型训练和优化,做出预测、分类和决策支持。Python成为机器学习的首选语言,…

Docker中使用自定义网络方式实现Redis集群部署与测试流程

场景 Docker中Docker网络-理解Docker0与自定义网络的使用示例: Docker中Docker网络-理解Docker0与自定义网络的使用示例-CSDN博客 参考上面的流程实现自定义网络的实现。 下面记录其应用实例,使用Docker的自定义网络实现redis集群部署。 注&#xf…

IP地址https证书的优势与申请途径

一、IP地址SSL证书的优势 无需域名:对于一些内部系统或者专用设备而言,它们可能不具有域名,但仍需保障通信安全。IP地址SSL证书正好满足这一需求。简化管理:对于拥有大量设备的企业来说,维护每个设备的域名可能是一个…

tomato-靶机渗透

tomato-靶机 一、安装靶机环境 下载双击.ova文件,写文件名路径导入 打开虚拟机用NAT模式 编辑–>虚拟网络编辑器查看IP段 二、信息收集 1.御剑端口扫描查找该虚拟机的IP 访问网站 扫目录 dirb http://192.168.30.130 收集到目录 /server-status /antibot_im…