每日一面——谈谈你对ReentrantLock的理解

菜鸡每日一面系列打卡16

每天一道面试题目 

助力小伙伴轻松拿offer

坚持就是胜利,我们一起努力!

题目描述

谈谈你对ReentrantLock的理解。

题目分析

在上一篇有关synchronized关键字的总结中,菜鸡曾提到过,互斥同步不仅可以通过synchronized关键字保证,还可以通过Lock接口保证。

不同于synchronized的JVM内置锁,Lock接口是类库层面的锁,相较于synchronized关键字来说,使用Lock接口实现同步有更大的操作空间,可以更好地应对更多复杂的场景。

本文要说的ReentrantLock就是Lock接口最常见的一种实现。在面试过程中,虽然出现频率不及synchronized关键字,但也算是面试过程中的常客,而且可考查的知识点相对来说比较多,其重要性也就不言而喻了。

接下来,随菜鸡一起去看看吧。

题目解答

01

概述

顾名思义,ReentrantLock是重入锁。它实现了Lock接口,是基于AQS(一种用于构建同步器的框架,后续会讲到)构造出来的一种同步器。

02

功能

同synchronized一样,ReentrantLock也是可重入的,与synchronized相比增加了一些高级功能,主要有以下三项:等待可中断、可实现公平锁、锁可以绑定多个条件

  • 等待可中断:是指当持有锁的线程长期不释放锁的时候,正在等待的线程可以选择放弃等待,改为处理其他事情。可中断特性对处理执行时间非常长的同步块很有帮助。

  • 公平锁:是指多个线程在等待同一个锁时,必须按照申请锁的时间顺序来依次获得锁;而非公平锁则不保证这一点,在锁被释放时,任何一个等待锁的线程都有机会获得锁。synchronized中的锁是非公平的,ReentrantLock在默认情况下也是非公平的,但可以通过带布尔值的构造函数要求使用公平锁。不过一旦使用了公平锁,将会导致ReentrantLock的性能急剧下降,会明显影响吞吐量。

  • 锁绑定多个条件:是指一个ReentrantLock对象可以同时绑定多个Condition对象。在synchronized中,锁对象的wait()跟它的notify()或者notifyAll()方法配合可以实现一个隐含的条件,如果要和多于一个的条件关联的时候,就不得不额外添加一个锁;而ReentrantLock则无须这样做,多次调用newCondition()方法即可。

值得注意的是,听起来好像觉得ReentrantLock无所不能,分分钟把synchronized秒成渣渣,然而并不是这样的,其实synchronized关键字有其特有的优势:

  • 使用简单,不易出错

  • 经过JVM底层的锁优化之后,二者的性能相差不大

  • JVM可以在线程和对象的元数据中记录synchronized中锁的相关信息,而如果使用ReentrantLock,JVM很难得知具体哪些锁对象是由特定线程所持有的。

03

整体结构

说了这么多,来看一下ReentrantLock的整体结构。

图中所示的FairSync即为ReentrantLock的公平锁实现,而NonfairSync为非公平锁实现。二者都继承了名为Sync的内部类,至于细节是如何实现的,这就涉及到了神奇的AQS模板类了,后续将会针对AQS类进行源码级别的剖析,届时一切谜底将被揭开。

以上便是菜鸡对ReentrantLock的一些总结,供大家参考。

参考资料

《深入理解Java虚拟机》周志明著

《Java并发编程实战》Brian Goetz等著

学习 | 工作 | 分享

????长按关注“有理想的菜鸡

只有你想不到,没有你学不到

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值