synchronized和ReentrantLock傻傻分不清楚

synchronized和ReentrantLock都是用于线程间同步的机制,都是可重入锁(同一个线程可以多次获取同一个锁),它们的异同点如下:
一、应用场景
1.synchronized可应用于实例方法、静态方法和代码块。
2.ReentrantLock 是 java.util.concurrent.locks 包下的一个具体类,实现了 Lock 接口。使用时需要显式创建 ReentrantLock 对象并调用其方法。


二、锁获取与释放机制
1.当进入或退出同步代码时,synchronized自动获取锁释放锁,执行完毕或抛出异常时自动释放锁。
2.ReentrantLock需要手动调用lock()获取锁,调用unlock()释放锁。若没有主动释放锁,可能导致死锁。推荐使用 try-catch-finally 或 try-with-resources 结构来确保锁的释放。


三、尝试非阻塞地获取锁:
1.synchronized 无法做到尝试非阻塞地获取锁。
2.ReentrantLock 提供了tryLock()方法,该方法尝试获取锁,如果成功则返回true,否则立即返回false,线程不会被阻塞。


四、锁的公平性
1.synchronized是非公平的,即在锁被释放时,任何一个等待锁的线程都有机会获得锁。
2.ReentrantLock默认情况下也是非公平的,但可以通过带布尔值为true的构造函数构造成公平锁。当ReentrantLock被配置为公平锁时,则多个线程在等待同一个锁时,必须按照申请锁的时间顺序来依次获得锁。


五、条件等待与通知
1.synchronized 通过 Object 类的 wait(), notify(), notifyAll() 方法来实现线程间的条件等待与通知。这些方法必须在 synchronized 代码块或synchronized修饰的方法中调用,否则会抛出 IllegalMonitorStateException。
2.ReentrantLock 可以通过 newCondition() 方法创建多个条件变量 Condition 对象。线程可以调用 condition.await() 进行等待,其他线程调用 condition.signal() 或 condition.signalAll() 进行通知。这种方式支持更精细的线程间协作,可以避免"伪唤醒"问题,使得线程等待特定条件而不是仅仅等待锁的释放。


六、可中断性
1.synchronized不支持正在等待锁的线程被中断。
2.ReentrantLock提供了lockInterruptibly()方法支持等待锁的线程被中断(若所在的线程被中断,则会抛出异常并释放当前获得的锁)。当持有锁的线程长期不释放锁的时候,正在等待的线程可以选择放弃等待,改为处理其他事情。


七、可配置性
1.在synchronized中,锁对象wait()、notify()或notifyAl()只能关联一个隐含的条件Condition,若要和多于一个的条件Condition关联不得不额外地添加一个锁。不可设置超时时间。
2.一个ReentrantLock对象可以使用tryLock(long timeout, TimeUnit unit)设置超时时间(超时后线程不会一直阻塞,而是立即返回一个布尔值表示是否成功获取锁),可以使用getOwner()或isHeldByCurrentThread()判断锁是否被本线程或其他线程持有,可以使用getQueuedThreads()获取等待此锁的线程集合,可以使用getWaitingThreads(Condition condition)获取等待在此锁上的某个Condition上的线程集合 ,可以通过多次调用newCondition()同时绑定多个Condition对象实现线程等待/通知机制。


八、性能
在高并发场景下,ReentrantLock的性能可能优于synchronized,因为它提供了更多的灵活性和控制选项。


九、锁优化机制
1.synchronized 的实现涉及到锁的升级,具体为无锁、偏向锁、自旋锁、重量级锁。
2.ReentrantLock 的实现则是通过利用 CAS(Compare And Swap)自旋机制保证线程操作的原子性和 volatile 保证数据可见性以实现锁的功能。


十、引申
1.synchronized 是JVM层面的同步,JVM会优化其性能,例如锁消除、锁粗化等。
2.ReentrantLock 是一个类,可以扩展,例如 ReentrantReadWriteLock 就是在 ReentrantLock 基础上实现的读写锁,提供了更复杂的读写权限控制。
3.synchronized在JVM中是采用 monitorenter 和 monitorexit 两个指令来实现同步的,monitorenter 指令相当于加锁,monitorexit 相当于释放锁。而 monitorenter 和 monitorexit 就是基于 Monitor 实现的。
4.ReentrantLock的常用的方法如下:
tryLock():尝试获取锁
getHoldCount():查询当前线程执行 lock() 方法的次数
getQueueLength():返回正在排队等待获取此锁的线程数
isFair():该锁是否为公平锁
hasQueuedThread(Thread thread):返回指定的线程是否在等待获取此锁
5.ReentrantLock中lock() 和 lockInterruptibly() 的区别:
获取锁的过程中如果所在的线程中断,lock() 会忽略异常继续等待获取锁,而 lockInterruptibly() 则会抛出 InterruptedException 异常。
6.synchronized实现锁升级的过程:
在锁对象的对象头里面有一个 ThreadID 字段,在第一次访问的时候 ThreadID 为空,然后JVM让其持有偏向锁,并将 ThreadID 设置为调用锁对象的线程 ID,再次进入的时候会先判断 ThreadID 是否与其线程 ID 一致,如果一致则可以直接使用,如果不一致,则升级偏向锁为轻量级锁,通过自旋来获取锁,不会阻塞,执行一定次数之后会升级为重量级锁(映射到操作系统提供的互斥锁Mutex Lock上)。
7.可以通过设置JVM参数UseHeavyMonitors禁用偏向锁和轻量级锁,直接使用重量级锁。
 


微风不燥,阳光正好,你就像风一样经过这里,愿你停留的片刻温暖舒心。我是程序员小迷(致力于C、C++、Java、Kotlin、Android、Shell、JavaScript、TypeScript、Python等编程技术的技巧经验分享),若作品对您有帮助,请关注、分享、点赞、收藏、在看、喜欢,您的支持是我们为您提供帮助的最大动力。

欢迎关注。助您在编程路上越走越好!

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

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

相关文章

使用Docker搭建Redis主从集群

文章目录 ☃️前言☃️搭建❄️❄️架构❄️❄️实例说明❄️❄️搭建第一个服务器上的两个实例❄️❄️搭建第二个服务器上的一个实例 ☃️开启主从❄️❄️改配置❄️❄️重启从节点 ☃️验证 ☃️前言 单节点 Redis 的并发能力是有上限的,要进一步提高Redis的并…

了解监控易(33):工单管理

在复杂的IT运维环境中,高效、规范地处理各种事务请求至关重要。监控易的工单管理功能,作为一款轻量化的运维协同工具,为团队提供了一个集中化、标准化的平台,以创建、接单、转交、挂起和重启工单,从而确保客户设备故障…

搜维尔科技:SenseGlove 的 Nova 被用于组装卫星接收器的虚拟现实培训项目中

SenseGlove 的 Nova 被用于组装卫星接收器的虚拟现实培训项目中 搜维尔科技:SenseGlove 的 Nova 被用于组装卫星接收器的虚拟现实培训项目中 得益于 SenseGlove 的力反馈专利,学员可以感受到他们正在组装的零件的形状、尺寸和密度。学员可以通过运动跟踪…

[大模型]TransNormerLLM-7B FastApi 部署调用

TransNormerLLM-7B FastApi 部署调用 1. TransNormer 介绍 TransNormerLLM 是一个基于线性注意力的 LLM,在准确性和效率方面均优于传统的基于 softmax 注意力的模型。它是在包含多达1.4 万亿个令牌的高质量语料库上进行训练的,TransNormerLLM 从之前的…

K-means和DBSCAN

目录 一、K-means和DBSCAN之间的主要区别 二、DBSCAN聚类算法 2.1DBSCAN聚类算法实现点集数据的聚类 2.2DBSCAN聚类算法实现鸢尾花数据集的聚类 三、K-means聚类算法 3.1K-means聚类算法实现随机数据的聚类 3.2K-means聚类算法实现鸢尾花数据集的聚类 一、K-means和DBSC…

014Node.js时间格式包silly-datetime安装与使用

下载: https://www.npmjs.com/网站上下载silly-datetime 安装 npm i silly-datetime --save var sd require(silly-datetime);console.log(new Date()); //2024-04-18T04:40:38.505Zvar dsd.format(new Date(), YYYY-MM-DD HH:mm);console.log(d); //2024…

未加权的相位解包裹算法DCT-0基础入门(含matlab代码和详细教程解析)

后面会更新c++ 的代码 ! phi = phase_unwrap(psi, weight) % get the wrapped differences of the wrapped valuesdx = [zeros([size(psi,1),1]), wrapToPi(diff(psi, 1, 2)), zeros([size(psi,1),1])];dy = [zeros([1,size(psi,2)]); wrapToPi(diff(psi, 1, 1)); zeros([1,s…

idea在controller或者service使用ctrl+alt+b进入方法后,如何返回到 进入前的那一层

idea在controller或者service使用ctrlaltb进入方法后,如何返回到进入方法的最外层 解决方案使用 ctrlalt ← /→← /→ 键盘上的左右键盘

jQuery 选择器有几种,分别是什么

jQuery选择器是用于“选择”(或查找)HTML元素的强大工具。jQuery选择器基于元素的名称、ID、类、类型、属性等进行选择。以下是jQuery选择器的几种主要类型,以及它们的详细代码示例: 基本选择器: 元素选择器&#xff1…

2024.4.20力扣每日一题——组合总和

2024.4.20 题目来源我的题解方法一 回溯 题目来源 力扣每日一题;题序:39 我的题解 方法一 回溯 以每一个位置开始深搜,直到target等于0或者小于0或者遍历完结束。 关键在于:注意去重 巧妙方法:传入一个index&#x…

stm32中断发送接收数据

配置hal库 1配置时钟 2配置uart 3打开中断 程序结构 uart中断函数 中断接收和发送函数 HAL_UART_Receive_IT():启动中断驱动的接收过程,当接收到指定数量的字节后会产生中断,并调用HAL_UART_RxCpltCallback()回调函数。 HAL_StatusTypeD…

Qt : 如何解决重载引起的歧义

一、引子 在Qt中编写代码,进行信号和槽函数的连接时,如果采用新的语法,如: connect(ui->doubleSpinBox, &QDoubleSpinBox::valueChanged,this,&App::minValueChanged);当你准备快乐编译时,突然被背刺。卧槽…

【Redis(6)】Redis集群模式配置示例

Redis的三种高可用方案对比参考上一篇博客:深入理解Redis三种高可用方案,以做出明智的选择,下面要探讨的是三种方案其中的一种。 在构建高性能缓存系统时,Redis以其卓越的速度和灵活性成为首选。然而,传统的哨兵模式和…

STL分解

效果图 ref:时序数据分析的利器——STL分解 - 知乎 (zhihu.com)

2024化工制造企业数字化白皮书

来源:蓝凌研究院 中国石油和化学工业联合会发布2023年中国石油和化工行业经济运行情况。数据显示,2023年,我国石化行业实现营业收入15.95万亿元, 同比下降1.1%,利润总额8733.6亿元,行业经济运行总体呈现低…

2024蓝桥杯每日一题(数学期望)

备战2024年蓝桥杯 -- 每日一题 Python大学A组 试题一:收集卡牌 试题二:爬树的甲壳虫 试题三:绿豆蛙的归宿 试题四:扑克牌 试题一:收集卡牌 【题目描述】 小林在玩一个抽卡游戏,其…

MySQL-笔记-06.数据高级查询

目录 6.1 连接查询 6.1.1 交叉连接(cross join) 6.1.2 内连接(inner join) 6.1.3 外连接(outer join) 6.1.3.1 左外连接(left [outer] join) 6.1.3.2 右外连接(rig…

LeetCode 1378、1277、2944

1378 二级排序&#xff0c;compare函数必须是static的 class Solution { public:struct node {int val;int priority;};static bool compare(const node &n1, const node &n2) {if (n1.priority n2.priority) {return n1.val < n2.val;}return n1.priority < n…

VSCode 目录折叠展开、缩进深度设置

1、VSCode 目录折叠展开设置 运行 Visual Studio Code &#xff0c;按 Ctrl &#xff0c;打开设置 输入Explorer:Compact Folders&#xff0c;取消勾选 或者在设置文件上添加 "explorer.compactFolders": false2、VSCode 目录缩进深度设置 输入Workbench Tree:…

【C# 数据结构-队列】

在C#中&#xff0c;队列&#xff08;Queue&#xff09;是一种先进先出&#xff08;First In First Out&#xff0c;FIFO&#xff09;的数据结构&#xff0c;允许添加&#xff08;Enqueue&#xff09;和移除&#xff08;Dequeue&#xff09;元素。队列类在.NET Framework的Syste…