【私藏好图】一张图看懂非公平锁与公平锁

2023-11-21 02:50

本文主要是介绍【私藏好图】一张图看懂非公平锁与公平锁,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

在 Java 并发编程中,公平锁与非公平锁是很常见的概念。

ReentrantLock、ReadWriteLock 默认都是非公平模式。

  • 非公平锁的效率为何高于公平锁呢?

  • 究竟公平与非公平有何区别呢?

首先先简单从名字上来理解,公平锁就是保障了多线程下各线程获取锁的顺序,先到的线程优先获取锁,而非公平锁则无法提供这个保障。

看到网上很多说法说非公平锁获取锁时各线程的的概率是随机的,这也是一种很不确切的说法。

非公平锁并非真正随机,其获取锁还是有一定顺序的,但其顺序究竟是怎样呢?先看画了半天的图:

公平锁与非公平锁的一个重要区别就在于上图中的 2、6、10 那个步骤,对应源码如下:
  //非公平锁final boolean nonfairTryAcquire(int acquires) {final Thread current = Thread.currentThread();int c = getState();if (c == 0) {//区别重点看这里if (compareAndSetState(0, acquires)) {setExclusiveOwnerThread(current);return true;}}else if (current == getExclusiveOwnerThread()) {int nextc = c + acquires;if (nextc < 0) // overflowthrow new Error("Maximum lock count exceeded");setState(nextc);return true;}return false;}//公平锁protected final boolean tryAcquire(int acquires) {final Thread current = Thread.currentThread();int c = getState();if (c == 0) {//hasQueuedPredecessors这个方法就是最大区别所在if (!hasQueuedPredecessors() &&compareAndSetState(0, acquires)) {setExclusiveOwnerThread(current);return true;}}else if (current == getExclusiveOwnerThread()) {int nextc = c + acquires;if (nextc < 0)throw new Error("Maximum lock count exceeded");setState(nextc);return true;}return false;}

分析以上代码,我们可以看到公平锁就是在获取锁之前会先判断等待队列是否为空或者自己是否位于队列头部,该条件通过才能继续获取锁。在结合兔子喝水的图分析,非公平锁获取所得顺序基本决定在 9、10、11 这三个事件发生的先后顺序, 1、若在释放锁的时候总是没有新的兔子来打扰,则非公平锁等于公平锁;2、若释放锁的时候,正好一个兔子来喝水,而此时位于队列头的兔子还没有被唤醒(因为线程上下文切换是需要不少开销的),此时后来的兔子则优先获得锁,成功打破公平,成为非公平锁;

其实对于非公平锁,只要线程进入了等待队列,队列里面依然是 FIFO 的原则,跟公平锁的顺序是一样的。因为公平锁与非公平锁的 release() 部分代码是共用 AQS 的代码。

private void unparkSuccessor(Node node) {int ws = node.waitStatus;if (ws < 0)compareAndSetWaitStatus(node, ws, 0);Node s = node.next;if (s == null || s.waitStatus > 0) {s = null;for (Node t = tail; t != null && t != node; t = t.prev)if (t.waitStatus <= 0)s = t;}if (s != null)//唤醒队列头的线程LockSupport.unpark(s.thread);}

总结

上文说到的线程切换的开销,其实就是非公平锁效率高于公平锁的原因,因为非公平锁减少了线程挂起的几率,后来的线程有一定几率逃离被挂起的开销。


作者:徐志毅

来源链接:

https://www.jianshu.com/p/f584799f1c77

这篇关于【私藏好图】一张图看懂非公平锁与公平锁的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/399311

相关文章

MiniGPT-3D, 首个高效的3D点云大语言模型,仅需一张RTX3090显卡,训练一天时间,已开源

项目主页:https://tangyuan96.github.io/minigpt_3d_project_page/ 代码:https://github.com/TangYuan96/MiniGPT-3D 论文:https://arxiv.org/pdf/2405.01413 MiniGPT-3D在多个任务上取得了SoTA,被ACM MM2024接收,只拥有47.8M的可训练参数,在一张RTX

一些数学经验总结——关于将原一元二次函数增加一些限制条件后最优结果的对比(主要针对公平关切相关的建模)

1.没有分段的情况 原函数为一元二次凹函数(开口向下),如下: 因为要使得其存在正解,必须满足,那么。 上述函数的最优结果为:,。 对应的mathematica代码如下: Clear["Global`*"]f0[x_, a_, b_, c_, d_] := (a*x - b)*(d - c*x);(*(b c+a d)/(2 a c)*)Maximize[{f0[x, a, b,

Oracle把一个表的某个字段更新到另一张表中

第一种方法: update tablea set column_name1=(select name2 from tableb where tableb.name3=tablea.name1) 只修改一个 update tablea set column_name1=(select name2 from tableb where tableb.name3='a') where tablea.na

阿里十年架构师用一张图告诉你什么是系统架构师

阿里十年架构师用一张图告诉你什么是系统架构师 Java架构解析 2018-11-03 20:54:41 这张图从架构师的综合能力、岗位认识、岗位职责等方面,清楚的画出了作为一个架构的基本准则。人人都想成为架构师,可作为架构你达到了图上面的要求了吗?   系统架构师是个神奇的岗位。为什么这么说,在一个人数不多的小公司,你可能什么都需要做,身体力行,做总监兼架构师或者是主管/高级开发兼架构

oracle存储过程Loop循环一张表插入到另外一张表

oracle存储过程Loop循环一张表插入到另外一张表   1、创建一个存储过程   Sql代码   create or replace procedure inserttest as   cursor cs is SELECT sales_id FROM t02salesinfo_backup;sales_id varchar(128);   begin   for c in c

项目实训:创建一张贺卡以及一只盒子——WEB开发系列27

以下是两道关于基础 CSS 盒模型和其他盒子相关特性的练习题,适合测试对这些概念的掌握程度,通过实际的设计任务来深入理解这些概念。 练习题 1: 设计一张中秋节海报贺卡 任务描述 制作一张精美的中秋节海报贺卡,用于庆祝这个传统节日。你的目标是应用 CSS 盒模型的各种属性来创建一个视觉上吸引人的海报,包括边距(margin)、边框(border)、内边距(padding)和内容区域(co

自然语言处理-应用场景-文本生成:Seq2Seq --> 看图说话【将一张图片转为一段文本】

人工智能-自然语言处理(NLP)-应用场景-Seq2Seq:看图说话【将一张图片转为一段文本】

团队动力之公平启发理论

不可不知的“公平启发理论” 公平启发理论‌主要用来回答如下问题: 公平感是如何产生的。公平感会对后续行为产生什么样的影响。 公平启发理论‌描述了人们在某个给定的情境下是如何构建自己的公平信念的,核心内容可以概括为两个阶段三个效应。两个阶段是指公平判断的形成和使用两个阶段。三个效应是指主因效应、替代效应以及其他效应。 两个阶段 ‌公平判断的形成阶段‌ 人们在日常生活中的决策更符合人们的生活实际