端午还在“修锁”?你是真的卷王!(二)

简介: 今天为你带来的是 ReentrantLock 公平锁与非公平锁的源码分析,它是 Java 并发包下的一个 java.util.concurrent.locks 实现类,实现了 Lock 接口和 Serializable 接口。

addWaiter() 方法就是将获取锁失败的线程加入到同步队列尾部。

70.png71.png


acquireQueued() 方法当节点为首节点的时候,再次调用 tryAcquire() 获取锁,否则就阻塞线程,等待被唤醒。


72.png73.png

shouldParkAfterFailedAcquire() 线程是否需要被阻塞,更改线程的 waitStatus 为 SIGNAL。parkAndCheckInterrupt() 实现真正的阻塞线程。

74.png

以上就是公平锁获取锁的全部过程,总结一下公平锁获取锁的过程:

  1. 当前线程调用 tryAcquire() 获取锁,成功则返回。
  2. 调用 addWaiter(),将线程封装成 Node 节点加入同步队列。
  3. acquireQueued() 自旋尝试获取锁,成功则返回。
  4. shouldParkAfterFailedAcquire() 将线程设置为等待唤醒状态,阻塞当前线程。
  5. 如果线程被唤醒,尝试获取锁,成功则返回,失败则继续阻塞。


非公平锁


用默认的构造方式创建一个非公平锁。lock() 方法上来就尝试抢占锁,失败则调用 acquire() 方法。


75.png

nonfairTryAcquire() 就没有绅士风度了,没有了公平锁 hasQueuedPredecessors() 方法。

76.png

以上就是非公平锁获取锁,总结一下非公平锁获取锁的过程:

  1. lock() 第一次尝试获取锁,成功则返回。
  2. nonfairTryAcquire() 再次尝试获取锁。
  3. 失败则调用 addWaiter() 封装线程为 Node 节点加入同步队列。
  4. acquireQueued() 自旋尝试获取锁,成功则返回。
  5. shouldParkAfterFailedAcquire() 将线程设置为等待唤醒状态,阻塞当前线程。
  6. 如果线程被唤醒,尝试获取锁,成功则返回,失败则继续阻塞。


公平锁和非公平锁对比


在下图源码中可以看出,公平锁多了一个 !hasQueuedPredecessors() 用来判断是否有其他线程比当前线程在同步队列中排队时间更长。除此之外,非公平锁在初始时就有 2 次获取锁的机会,然后再到同步队列中排队。

77.png


unlock() 释放锁


获取锁之后必须得释放,同一个线程不管重入了几次锁,必须得释放几次锁,不然 state 变量将不会变成 0,锁被永久占用,其他线程将永远也获取不到锁。

78.png79.png

释放锁的逻辑就是 state 必须被减去 1 直到为 0,才可以唤醒下一个线程。

总结

ReentrantLock 主要是防止资源的使用冲突,保证同一个时间只能有一个线程在使用资源。比如:文件操作,同步发送消息等等。

本文分析了 ReentrantLock 的公平锁和非公平锁以及释放锁的原理,可以得出非公平锁的效率比公平锁效率高,非公平锁初始时会 2 次获取锁,如果成功可以减少线程切换带来的损耗。在非公平模式下,线程可能一直抢占不到锁。

我是指北君,操千曲而后晓声,观千剑而后识器。感谢各位人才的:点赞、收藏和评论,我们下期更精彩!


相关文章
|
6月前
|
数据安全/隐私保护
BUUCTF 穿越时空的思念 1
BUUCTF 穿越时空的思念 1
136 1
|
存储 安全 关系型数据库
我,卷王!
MySQL 里面表级别的锁有这几种: • 表锁; • 元数据锁(MDL); • 意向锁; • AUTO-INC 锁;
我,卷王!
端午还在“修锁”?你是真的卷王!(一)
哈喽,大家好,我是指北君。 今天为你带来的是 ReentrantLock 公平锁与非公平锁的源码分析,它是 Java 并发包下的一个 java.util.concurrent.locks 实现类,实现了 Lock 接口和 Serializable 接口。
端午还在“修锁”?你是真的卷王!(一)
小树的 2020 年终总结
一些关于 2020 的记忆。
179 0
小树的 2021 年终总结
2021.07.17 摄于威海魔幻的 2021 过去了,和大家聊聊自己这一年来的经历和感受。成家今年最大的收获是「成家」。4 月底的时候确定婚期,5 月初马不停蹄地确定了婚庆公司,试婚纱、试西服。6 月 6 日在家里精心布置,完成求婚。7 月中敲定婚纱照公司,完成拍摄。8 月开始了非常密集的婚礼策划沟通。9 月回家试妆,购置婚房用品,9 月底提前一周回家每天都在购置婚庆用品,反复确认各种细节。婚礼
159 0
小树的 2021 年终总结
|
敏捷开发 人工智能 前端开发
2019年年终总结
又到了一年一度的年终总结时间, 还记得去年这一天吗? 时间真的很快, 转眼告别 10 年代, 迎接 2020 年, 回归鼠年; 这一年经历了风风雨雨, 回首一年的成就和挫折, 都不禁充满激动, 有成功, 有失败, 有感动, 有焦虑, 都随着 2020 年的到来挥之而去, 在这里祝大家元旦快乐! 提前拜个早年! 下面总结一下 2019 年的工作, 生活以及成长! 一、 2019 年曾立下的Flag 管它能否实现, 先立下 Flag 再说! 2019 年喜忧参半, 完成率 50%。
9115 0
追梦
怀揣梦想背对晚霞化入黑暗等待晨曦那时他人还在熟睡我将是第一个暮光之人继续在质疑与否定中保持苦逼和自信地微笑 2018年5月6日,下午,于榴花
6104 0
|
iOS开发
2017年年终总结
前言 不知不觉,2017年又接近尾声了,又到了该写年终总结的时候了,往年这个时候都会熙熙攘攘,各大平台提早预热过年的气氛,而今年显得格外的平静,这可能正如我的现在的心境,波澜而不惊!因为今年整体过的只能说并不太圆满,事业上颇丰,感情略欠缺。
1824 0