<多线程章节五>synchrosized的可重入特性

💐专栏导读

本篇文章收录于多线程,也欢迎翻阅博主的其他文章,可能也会让你有不一样的收获😄
🍁JavaSE 🌺多线程 🍂数据结构

💐synchrosized的可重入特性及死锁

可重入特性就是:当一个线程针对一个对象同时加锁两次,不会构成死锁,这样的特性称为可重入性;

例如下图例子:

在这里插入图片描述

为了防止上述死锁情况,synchrosized就引入了可重入性解决;

线程在加锁时,在这个锁对象内部,它会记录是对哪个线程加了锁,当对同一个线程再次进行加锁时,就会判断该线程是不是同一个线程并且是否已经持有了锁,如果已经有了锁,那么也会重复进行加锁,不会导致死锁现象;

**那么,问题就来了,如果加两次锁,在 }2 时是否应该解锁呢?**答案:不能释放锁

在这里插入图片描述

如果加了n次锁呢?该怎么去释放呢?

答案:在锁对象中,不仅会记录对哪个线程加了锁,还会有一个计数器记录加锁的次数;当每次执行完一个加锁的代码块时,计数器就会减1,一直到最后一个锁时,才会释放锁;

关于死锁:

1.在Java中,如果一个线程对同一个锁连续加锁两次,不会造成死锁现象

2.如果两个线程,两把锁,每个线程都加两个不同的锁(嵌套加锁),就会造成死锁现象

例如:让线程1先获取锁1,线程2获取锁2,然后在锁1的内部再尝试获取锁2, 再锁2的内部再尝试获取锁1

public static void main(String[] args) {//定义两把锁Object lock1 = new Object();Object lock2 = new Object();//让线程1嵌套获取两把锁Thread thread1 = new Thread(() -> {synchronized (lock1) {//此处睡眠很重要,如果没有睡眠,线程1可能就会一下子把两把锁都获取了,就构不成死锁现象了try {Thread.sleep(1000);} catch (InterruptedException e) {throw new RuntimeException(e);}synchronized (lock2) {System.out.println("thread1加锁成功");}}});//让线程2嵌套获取两把锁Thread thread2 = new Thread(() -> {synchronized (lock2) {try {Thread.sleep(1000);} catch (InterruptedException e) {throw new RuntimeException(e);}synchronized (lock1) {System.out.println("thread2加锁成功");}}});thread1.start();thread2.start();}

在这里插入图片描述

3.n个线程,m把锁,更容易出现死锁问题,例如哲学家就餐问题:

哲学家就餐问题:

在这里插入图片描述

死锁是一个比较严重的bug,那如何避免/解决死锁呢?

💡如何避免/解决死锁

要想避免死锁,就要先直到死锁是怎么形成的,这样才能对症下药,导致死锁的四个必要条件:

1.互斥使用:当线程1获取锁之后,线程2也想获取同一把锁,就会阻塞等待(锁的特性)

2.不可抢占:当线程1已经获取到锁之后,线程2不能强行抢占锁(锁的特性)

3.请求保持:一个线程尝试获取多把锁(一个线程获取到锁1之后,还想尝试获取锁2,此时锁1也并未解锁)例如上面的

4.循环等待:线程获取锁时,形成了环路;例如,上面哲学家同时拿起左边的筷子

第一点和第二点是锁的特性,如果想要解决死锁,就要破坏第三点和第四点,

对于第三点来讲,只要避免两把不同的锁嵌套获取即可

在这里插入图片描述

对于第四点来讲,可以约定给所有的锁进行一个编号,规定所有的线程只能按顺序先获取编号小的锁,然后获取编号大的锁,例如:

在这里插入图片描述

在这里插入图片描述

以上虽然时嵌套加锁的,但是并未形成环路,得到lock1锁的线程执行,未获得lock1的线程阻塞等待,并且也无法获得lock2

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

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

相关文章

力扣每日一题79:单词搜索

题目描述: 给定一个 m x n 二维字符网格 board 和一个字符串单词 word 。如果 word 存在于网格中,返回 true ;否则,返回 false 。 单词必须按照字母顺序,通过相邻的单元格内的字母构成,其中“相邻”单元格…

如何查找特定基因集合免疫基因集 炎症基因集

温故而知新,再次看下Msigdb数据库。它更新了很多内容。给我们提供了一个查询基因集的地方。 关注微信:生信小博士 比如纤维化基因集: 打开网址:https://www.gsea-msigdb.org/gsea/msigdb/index.jsp 2.点击search 3.比如我对纤维…

如何让Java的线程池顺序执行任务?

Java中的线程池本身并不提供内置的方式来保证任务的顺序执行的,因为线程池的设计目的是为了提高并发性能和效率,如果顺序执行的话,那就和单线程没区别了。 但是如果被问到想要实现这个功能该怎么做,有以下两种方式。 1.使用单线…

结构体数组经典运用---选票系统

结构体的引入 1、概念:结构体和其他类型基础数据类型一样,例如int类型,char类型,float类型等。整型数,浮点型数,字符串是分散的数据表示,有时候我们需要用很多类型的数据来表示一个整体&#x…

软考 系统架构设计师系列知识点之设计模式(6)

接前一篇文章:软考 系统架构设计师系列知识点之设计模式(5) 所属章节: 老版(第一版)教材 第7章. 设计模式 第2节. 设计模式实例 相关试题 1. 设计模式描述了一个出现在特定设计语境中的设计再现问题&…

Parity 战略转型引热议,将如何推动波卡生态去中心化?

Polkadot 生态的区块链基础设施公司 Parity Technologies,最近宣布了一项重要的战略调整,即正在寻求在未来几个月内,将部分现有的市场职能转移给 Polkadot 生态系统内的多个去中心化团队,这将影响 Parity Technologies 未来几个月…

ffmpeg中examples编译报不兼容错误解决办法

ffmpeg中examples编译报不兼容错误解决办法 参考examples下的README可知,编译之前需要设置 PKG_CONFIG_PATH路径。 export PKG_CONFIG_PATH/home/user/work/ffmpeg/ffmpeg/_install_uclibc/lib/pkgconfig之后执行make出现如下错误: 基本都是由于库的版…

(el-Table)操作(不使用 ts):Element-plus 中 Table 多选框的样式等的调整

Ⅰ、Element-plus 提供的 Table 表格组件与想要目标情况的对比: 1、Element-plus 提供 Table 组件情况: 其一、Element-ui 自提供的 Table 代码情况为(示例的代码): // Element-plus 自提供的代码: // 此时是使用了 ts 语言环境…

企业管理系统有哪些?

文章目录 企业管理系统一、ERP 企业资源计划(Enterprise Resource Planning)二、OMS 订单管理系统(Order Management System)三、WMS 仓库管理系统(Warehouse Management System )四、TMS 运输管理系统 (Tr…

第十三章---枚举类型与泛型

一,枚举类型 1.使用枚举类型设置常量 设置常量时,我们通常将常量放置在接口中,这样在程序中就可以直接使用。该常量稚因为在接口中定义常量时,该常量的修饰符为 final 与 static。 public interface Constants ( public static …

LVS集群-DR模式【部署高可用LVS-DR集群】

文章目录 2.2 实战:配置LVS-DR集群2.2.1 配置IP(Director Server的部署配置)2.2.2 生成ens33:1配置文件 (Director Server的部署配置)2.2.3 配置LVS-DR规则(Director Server的部署配置)2.2.4 两…

Docker 镜像读写层核心概念:rootfs、Union mount、image以及layser原理详解

Docker 镜像读写层核心概念:rootfs、Union mount、image以及layser原理详解 文章目录 Docker 镜像读写层核心概念:rootfs、Union mount、image以及layser原理详解rootfsUnion mount为什么镜像层都是只读的去掉读写层的话会有什么问题 Docker镜像imageDoc…

AcWing 1.2.1 最长上升子序列模型 + 动态规划 + 图解(详细)

(1)acwing 4557. 最长上升子序列 4557. 最长上升子序列 - AcWing题库 给定一个长度为 N 的整数序列 a1,a2,…,aN。请你计算该序列的最长上升子序列的长度。上升子序列是指数值严格单调递增的子序列 输入格式 第一行包含整数 N第二行包含 N个整数 a1,a…

大语言模型(LLM)综述(四):如何适应预训练后的大语言模型

A Survey of Large Language Models 前言5. ADAPTATION OF LLMS5.1 指导调优5.1.1 格式化实例构建5.1.2 指导调优策略5.1.3 指导调优的效果5.1.4 指导调优的实证分析 5.2 对齐调优5.2.1 Alignment的背景和标准5.2.2 收集人类反馈5.2.3 根据人类反馈进行强化学习5.2.4 无需 RLHF…

一个比较特别的串口工具

这是08年写的一个 并网带电池逆变器 的通讯工具,和普通的串口调试器相比,多了一个【脚本】功能。能够通过【脚本】完成通讯测试。 PC发给DSP的01命令 01 10 1B 00 CF A3 00 00 90 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 电…

使用 @antfu/eslint-config 配置 eslint (包含兼容uniapp方法)

安装 pnpm i -D eslint antfu/eslint-config创建 eslint.config.js 文件 // 如果没有在 page.json 配置 "type": "module" const antfu require(antfu/eslint-config).default module.exports antfu()// 配置了 "type": "module" …

小程序开发——小程序的事件

1.事件对象 事件与事件对象概述 事件是一种用户行为,用户的点击、滑动等操作都可以成为事件。事件也是一种通信方式,能够完成视图层(WXML页面文件)与逻辑层(JS逻辑文件)之间的通信。 事件对象是指用户在点…

uniapp开发app,在ios真机上出现的css样式问题

比如下面的问题,在iphone 13上出现,在iphone xR上正常。 问题一:border:1rpx造成边框显示不全 在iphone13上border边框有一部分不显示: 在iphone xR上显示正常: 解决办法是: 将border边框设置中的1rpx改…

Burp Suite配置过滤忽略Ruby code injection和XML injection类型的安全问题

可以使用扫描配置中的"Active Scan"选项。请按照以下步骤进行配置: 打开Burp Suite并启动您的目标应用程序。 载入您的目标应用程序并确保它已配置为代理Burp Suite。 转到Burp Suite的"Proxy"选项卡,并确保Proxy Server正在运行。…

eslint识别不了别名解决方法

第一步 npm i eslint-import-resolver-alias -D第二步:在 eslintrc.js 配置 module.exports {settings: {import/resolver: {alias: {map: [// 这里参照webpack的别名配置映射[, ./src]],// 引用的时候可以忽略后缀extensions: [.vue, .js, .ts, .tsx, .jsx, .json…