浅谈ReentrantLock的公平锁和非公平锁的区别

news2024/11/20 20:25:03

前言

最近在看java并发编程这本书,已经看了点ReentrantLock的源码,以及之前有面试官问,公平锁和非公平锁有啥区别,我就只是从源码层面说了一下区别,但在性能上也有区别,今天就来说道说道。

公平与非公平

ReentrantLock的构造函数中提供了两种选择,默认创建非公平锁,也可以指定创建公平锁。
在公平锁上,线程将按照他们发出的请求顺序来获取锁,如果有另外一个线程持有这个锁或者有其他线程在队列中等待这个锁,那么新发出请求的线程就会被放到队列中。
在非公平锁上,允许“插队”:当一个线程请求非公平的锁时,如果在发出请求的同时该锁的状态变为可用,这个线程就会跳过队列中所有等待线程直接抢到这个锁。只有当锁被某个线程持有的时候,新发出请求的线程才会被放入队列中。

如何选择公平或非公平锁

为什么会有公平和非公平之分呢?我们都普遍认为一个公平的世界是一个稳定而温馨的世界,而不公平被认为不是好事,那么在锁的世界中如何呢?
当执行加锁操作时,公平性将由于挂起线程和恢复线程时存在的开销而大大降低性能。在实际的大多数情况中,非公平锁的性能要远高于公平锁的性能。

下图是Map的性能测试,并比较有公平的以及非公平的ReentrantLock包装的HashMap的性能,从图中可以看出,公平性把性能降低了约2个数量级:
在这里插入图片描述

备注ConcurrentHashMap在线程数为4到8之间有一些波动,这个波动属于测量噪声,这种噪声在性能测试中常有,对整体结果不造成实质性影响可不做过度关注。

从上图可以看出来,在激烈竞争下,非公平锁的性能远高于公平锁的性能,其原因是:在恢复一个被挂起的线程 与线程真正开始运行之间存在着严重的延迟。

  • 假设线程A持有一个锁,并且线程B请求这个锁。
  • 由于这个锁已经被线程A持有了,线程B将被放入队列中挂起。
  • 当A释放锁时,B将被唤醒,因此会再次尝试获取锁。
  • 与此同时,正好有个C线程来请求这个锁,那么C线程很有可能在B被完全唤醒之前抢到,使用以及释放这个锁。
  • 等C线程使用完释放后,B线程正好被唤醒,获取此锁并使用。

如此赢得了双赢的局面,线程B获取锁的时间并没有被延迟,C也在B唤醒的空挡中干完了自己的工作,因此最终的吞吐量也得以提高。

那么什么时候使用公平锁呢?
当持有的锁的时间相对较长,或者请求锁的平均时间间隔较长,那么应该使用公平锁。在这种情况下,“插队”带来的吞吐量的提升(当锁处于可用状态时,线程却还处于被唤醒的过程中)则可能不会出现。

ReentrantLock与内置锁

说到锁就不得不提我们最熟悉的内置锁:Sychronized,那么这两种锁又该如何选择呢?
ReentrantLock相比内置锁还通了包括定时的锁等待,可中断的锁等待,公平性,以及实现非块结构的枷锁。其性能上似乎是优于内置锁,其中在Java6略有胜出,在Java5则远远胜出。既然如此,我们为什么不抛弃内置锁,直接选择ReentrantLock呢?
原因在于

  • ReentrantLock的危险性比内置锁要高,如果忘记在finaly块中调用unlock方法,却虽然代码表面上可以正常运行,但却等于埋了一颗定时炸弹,还有可能伤及无辜。
  • 另外,Sychronized还有一个ReentrantLock所没有的优点,就是在线程转储中能给出在哪些调用帧中获得了那些锁,并能够检测和识别发生死锁的线程。在Java6中还提供了给管理和调试接口,锁可以通过该接口进行注册,从而一些相关的加锁信息就能出现在线程转储中,给程序员带来一些帮助。而ReentrantLock的非块状结构特性获取锁的操作不能与特定的栈帧关联起来,而内置锁却可以。
  • 未来更可能会提升Sychronized而不是ReentrantLock的性能。因为Sychronized是JVM内置属性,它能执行一些优化,例如对线程封闭的锁对象的锁消除优化,Java6开始的锁升级的优化。

那么什么时候该选择ReentrantLock呢?
在一些内置锁无法满足需求的情况下,ReentrantLock可以作为一种高级工具。当需要一些高级功能的时候才应该使用ReentrantLock,比如可定时的,可轮询的与可中断的锁获取操作,公平队列,以及非块状结构的锁。否则还是应该优先使用内置锁Sychronized

---------------你知道的越多,不知道的越多--------------

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

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

相关文章

Exponentiation

Exponentiation is a mathematical operation, written as bn, involving two numbers, the base b and the exponent or power n, and pronounced as “b (raised) to the (power of) n”.[1] When n is a positive integer, exponentiation corresponds to repeated multipli…

Mac卸载mysql并重新安装mysql

一、Mac卸载mysql 1、在系统偏好设置找到MySQL服务—>停止 2、打开终端 sudo rm /usr/local/mysql sudo rm -rf /usr/local/var/mysql sudo rm -rf /usr/local/mysql* sudo rm -rf /Library/StartupItems/MySQLCOM sudo rm -rf /Library/PreferencePanes/My* vim /etc/ho…

财务分析和经营分析有什么区别和联系

财务分析是基础,经营分析是建立在财务分析基础之上的专项分析。财务分析做诊断,经营分析要治病。财务分析旨在通过财务指标发现和洞察问题,经营分析针对财务分析发现的问题进行深入的重点分析,以解决最终问题为目标。 财务分析 -…

世界上最伟大最邪恶的软件发明

有这么一个伟大而“邪恶”的软件发明,它被安装在超过10亿台电脑中,每天被使用超过3000万次。世界上几乎每个组织都在使用它,不仅有大大小小的公司,还有企业家、艺术家、非营利组织、学校、政府和宗教领袖,它已经成了公…

Allegro如何翻转PCB视图操作指导

Allegro如何翻转PCB视图操作指导 Allegro可以翻转PCB的视图,利于查看和检查,如下图 翻转前:器件和走线在bottom层 翻转后:走线和器件仍然在bottom层,但是视图翻转了 具体操作如下

高等数学(第七版)同济大学 习题11-2 个人解答

高等数学(第七版)同济大学 习题11-2 函数作图软件:Mathematica 1.设L为xOy面内直线xa上的一段,证明:∫LP(x,y)dx0.\begin{aligned}&1. \ 设L为xOy面内直线xa上的一段,证明:\int_{L}P(x, \ …

【运维有小邓】Active Directory的NTFS权限报表程序

使用此简化的NTFS权限工具分析和优化共享权限和访问控制列表(ACL)。 ADManager Plus是我们的Active Directory管理和报表解决方案,可以兼用作共享文件夹权限报表工具。它提供预定义的报表,以查看,分析和修改NTFS并共享…

CSS -- 07. CSS3新特性汇总(属性选择器,结构伪类,伪元素,过渡效果,动画,2D3D转换效果)

文章目录CSS 3的新特性1 CSS 3的现状2 属性选择器3 结构伪类选择器3.1 选择第n个孩子3.2 nth-child(n)3.3 nth-of-type()3.4 nth-child和nth-of-type的区别3.5 结构伪类选择器小结4 伪元素选择器4.1 案例:经过盒子显示遮罩层4.2 伪元素清除浮动5 CSS 3盒子模型6 CSS…

比较叶绿体基因组提供海草适应性进化新见解

一、摘要 海草是生活在热带和亚热带地区的海洋开花植物,所有海草物种都是从陆地单子叶植物进化而来的,是研究植物对海洋环境适应的重要材料。本研究对三个鳗草属海草的叶绿体基因组(cpGenomes)进行测序,分析、比较三者…

Python图形用户界面(GUI)编程之wxPython入门

图形用户界面主要是方便用户操作,Python开源的GUI类库还是蛮多的,这里介绍一款在Python语言中的一套优秀的GUI图形库,而且是跨平台的,现今支持的平台有:32/64位微软Windows操作系统、大多数Unix或类Unix系统、苹果Mac …

如何解密PDF文件?这些解密方法快来收藏

有时候我们为了确保PDF文档不被他人随意查看,会对文档进行加密操作。但如果需要给某位同事查看的话,就需要每次输入密码才能查看文档,那你们知道PDF文档解密怎么弄吗?今天给大家分享几种实用的PDF解密技巧,有需要的小伙…

同为(TOWE)远程智能防雷预警监测——交直流遥信防雷配电柜

当前,社会各领域中各类先进的电子仪器广泛分布于每一个角落,由于高精尖电子设备的高度集成化,其耐压水平普遍较低,导致雷电流、浪涌侵入设备的风险越来越高,故需要在重要设备前端加装浪涌保护器(SPD&#x…

vue3项目打包部署到Tomcat(亲测有效)

首先,要确保电脑上已经安装了jdk,还有Tomcat,而且都安装正确。 jdk下载与安装教程(win10) Tomcat 9.0 安装及配置教程(win10系统) Vue项目在VScode里面可以通过npm run serve可以正常运行。 下面是打包部署到tomca…

单体优先的微服务架构

作者:Martin Fowler 译者:林宁 当听说有团队在使用微服务架构时候,我注意到了一些规律: 几乎所有成功应用微服务的系统,都来自于一个过大单体项目拆分而来。几乎所有我听到过一开始就选择使用微服务架构的系统&#x…

【软件测试】测试开发?开发一个自动化测试系统如何做?

目录:导读前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结(尾部小惊喜)前言 当我们开始分析一个…

ADI Blackfin DSP处理器-BF533的开发详解67:PCM的播放(含源码)

硬件准备 ADSP-EDU-BF533:BF533开发板 AD-HP530ICE:ADI DSP仿真器 软件准备 Visual DSP软件 硬件链接 代码实现功能 代码实现了打开代码工程目录下的“test.snd”文件,并读取 6MB 的数据到内存中,然后将内存中的数据进行循环…

C语言重点解剖第17课笔记

1.预处理阶段,先去注释,再宏替换。所以宏替换不能用于去注释。 #define bsc //就变成了一个空的宏。(//在这里面本来就是注释,只是注释后面的内容为空) 2.宏定义并不是简单的无脑替换。 printf(" ")中,双引号里面的东…

uniCloud云开发----3、uniApp中文件上传(通过插件(uniFilePicker)或者 uniCloud.uploadFile实现方案)

uniApp中文件上传前言效果图1、使用unifilePicker插件(1)安装unifilePicker插件(2)简单案例2、通过原生的 uniCloud.uploadFile来实现共同成长共同进步前言 uniapp图片上传插件unifilePicker 在开发uniapp的时候上传文件是必不可…

从月入5千到现在的月入1W+,会计转程序员,“谁说女的不适合学编程?”

前言 我毕业五年了,但与技术和 Python 相关的工作经验也就两年。今天我想跟大家分享自己转行的故事,希望能够鼓励那些跟我一样的朋友共同前行。 我们将会聊到我个人的经历和入行故事,讨论快速学习的方法,最后推荐一些学习资源。…

“互联网+”获奖项目专访 | 阿尔兹海默症患者辅助诊断研究分享

在本届“互联网”创新创业大赛中 昇思MindSpore群英荟萃团队荣获全国总决赛铜奖 本期有幸邀请到 团队负责人李鹏和指导老师胡悦进行采访 一起来看看夺奖背后的故事吧 PART ONE 团队介绍 群英荟萃团队 1. 项目成员 李鹏、周晨、邹静、纪雨萍、李晓迪、张英豪 2. 指导老…