腾讯面试题 你了解ReentrantLock吗?
腾讯面试题 你了解ReentrantLock吗?
ReetrantLock是一个可重入的独占锁,主要有两个特性,一个是支持公平锁和非公平锁,一个是可重入。
ReetrantLock实现依赖于AQS(AbstractQueuedSynchronizer)(不懂得话可以看我上篇博客)。
ReetrantLock主要依靠AQS维护一个阻塞队列,多个线程对加锁时,失败则会进入阻塞队列。等待唤醒,重新尝试加锁。下图是其类图
支持公平锁和非公平锁
公平锁:多个线程申请获取同一资源时,必须按照申请顺序,依次获取资源。
非公平锁:资源释放时,任何线程都有机会获得资源,而不管其申请顺序。
具体原理分析
在new
ReetrantLock
对象的时候,可以指定其支持公平锁还是非公平锁public ReentrantLock() {sync = new NonfairSync(); }public ReentrantLock(boolean fair) {sync = fair ? new FairSync() : new NonfairSync(); }
公平锁原理
FairSync
继承Sync,而Sync继承AbstractQueuedSynchronizer
。ReentrantLock调用lock
方法,最终会调用sync的tryAcquire
函数,获取资源。FairSync的tryAcquire
函数,**当前线程只有在队列为空或者时队首节点的时候,才能获取资源,否则会被加入到阻塞队列中。**下面的hasQueuedPredecessors
函数用于判断队列是否为空,或者当前元素是否为队首元素。static final class FairSync extends Sync {private static final long serialVersionUID = -3000897897090466540L;final void lock() {acquire(1);}protected final boolean tryAcquire(int acquires) {final Thread current = Thread.currentThread();int c = getState();if (c == 0) {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;} }
hasQueuedPredecessors
函数,如果h==t
(队列为空),或者h!=t && s.thread == Thread.currentThread()
(队首节点),则返回false,否则返回truepublic final boolean hasQueuedPredecessors() {Node t = tail; // Read fields in reverse initialization orderNode h = head;Node s;return h != t &&((s = h.next) == null || s.thread != Thread.currentThread()); }
非公平锁原理
NoFairSync
同样继承Sync,ReentrantLock调用lock
方法,最终会调用sync的tryAcquire
函数,获取资源。而NoFairSync的tryAcquire
函数,会调用父类Sync的方法nofairTryAcquire
函数。通过对比可以发现,如果资源释放时,新的线程会尝试CAS操作获取资源,而不管阻塞队列中时候有先于其申请的线程。static final class NonfairSync extends Sync {private static final long serialVersionUID = 7316153563782823691L;final void lock() {if (compareAndSetState(0, 1))setExclusiveOwnerThread(Thread.currentThread());elseacquire(1);}protected final boolean tryAcquire(int acquires) {return nonfairTryAcquire(acquires);} }
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; }
可重入性
可重入性:获取独占资源的线程,可以重复得获取该独占资源,不需要重复请求。
请求独占资源时,可重入性的体现
ReentrantLock在申请资源的时候,都会判断当前持有独占资源的线程是不是当前线程,如果是的话,只是简单得将state值加1.记录当前线程的重入次数。
else if (current == getExclusiveOwnerThread()) {int nextc = c + acquires;if (nextc < 0)throw new Error("Maximum lock count exceeded");setState(nextc);return true;}
释放资源时,可重入性的体现
ReentrantLock在释放资源的时候,都会调用
tryRelease
,只有state值为0的时候,才会释放资源。换句话说就是,重入多少次,就必须释放多少次protected final boolean tryRelease(int releases) {int c = getState() - releases;if (Thread.currentThread() != getExclusiveOwnerThread())throw new IllegalMonitorStateException();boolean free = false;if (c == 0) {free = true;setExclusiveOwnerThread(null);}setState(c);return free; }
腾讯面试题 你了解ReentrantLock吗?相关推荐
- android获取指针空间大小_腾讯笔试题:浅谈计算机中cpu位数和指针
来一个腾讯笔试题 在刷题的时候看到了腾讯笔试题的这个问题 long a = (long)(((int *) 0) + 4);printf("%ld ",a); 请问输出 a 的值是 ...
- 腾讯面试题:char 和 varchar的最大长度是多少,以及他们之间的区别(看完你就能和面试官笑谈人生了)
title: 腾讯面试题:char 和 varchar的最大长度是多少,以及他们之间的区别(看完你就能和面试官笑谈人生了) tags: 面试常见题 腾讯面试题:char 和 varchar的最大长度是 ...
- 腾讯面试题:创建索引时,你会怎么考虑呢?(看完你就能和面试官谈人生了)
title: 腾讯面试题:创建索引时,你会怎么考虑呢?(看完你就能和面试官谈人生了) tags: 面试常见题 腾讯面试题:创建索引时,你会怎么考虑呢?(看完你就能和面试官谈人生了) 腾讯面试题:创建索 ...
- 腾讯面试题:给40亿个不重复的unsigned int的整数,没排过序的,然后再给一个数,如何快速判断这个数是否在那40亿个数当中?
1.腾讯面试题:给40亿个不重复的unsigned int的整数,没排过序的,然后再给一个数,如何快速判断这个数是否在那40亿个数当中? 思想:用数组来存这40亿个数,而且只能用bit来表示.why? ...
- 【转】IT名企面试:腾讯笔试题(2)
摘要:想要进入腾讯公司,面试笔试题是一定要有所准备的.那么这里我们总结了一些腾讯笔试题,例如:const的含义及实现机制等问题. 腾讯是国内数一数二的IT企业了.那么每年想要进入腾讯公司的应聘者也是络 ...
- 线性表11|单链表小结:腾讯面试题 - 数据结构和算法16
线性表11|单链表小结:腾讯面试题 让编程改变世界 Change the world by program 静态链表的删除操作 我们的故事还没结束,小C看到小A和2B这样非法的勾当,内心觉得很不爽,一 ...
- 程序员求助:腾讯面试题,64匹马8个跑道,多少轮选出最快的四匹
昨天,有网友私信我,说去阿里面试,彻底的被打击到了.问了为什么网上大量使用ThreadLocal的源码都会加上private static?他被难住了,因为他从来都没有考虑过这个问题.无独有偶,今天笔 ...
- java 2017腾讯面试题_腾讯2017刁难面试题,是不是大神就看你会做几题
原标题:腾讯2017刁难面试题,是不是大神就看你会做几题 一.今日头条2017笔试题(决策问题) 现在有两堆石子,小今与小条玩游戏,2个人都足够聪明,两个人规定:每次每人只能从其中一堆中取走1个或2个 ...
- python编辑距离正则匹配_详解一道腾讯面试题:编辑距离
原标题:详解一道腾讯面试题:编辑距离 来自公众号:labuladong 预计阅读时间:8 分钟 前几天在网上看到一份鹅场的面试题,算法部分大半是动态规划,最后一题就是写一个计算编辑距离的函数,今天就专 ...
最新文章
- PoweMock集成Spring-test 测试静态方法 禁用字节码验证 -noverify -XX:-UseSplitVerifier
- HTTP对外接口,如何增加签名机制
- Spring :Spring Aop 创建代理
- 使用gRPC的.NET Core 3.0双向消息流
- Java基础学习总结(65)——Java中的String,StringBuilder和StringBuffer比较
- Java 实现HTML 页面转成image 图片
- oracle 拉链表 计算和,Oracle拉链表和流水表如何按照时间匹配求新的计算项
- ubuntu 12.04 server + OPENACS(TR069)安装配置日记
- 对于“增霸卡“的介绍跟使用
- Android中的像素密度,屏幕密度,屏幕大小,分辨率,ldpi,mdpi,xhdpi,xxhdpi
- 安卓电视/平板玩街机游戏
- STM32F407 ETR 计数程序
- java计算机毕业设计民航售票管理系统源代码+数据库+系统+lw文档
- Word文档怎么翻译?翻译word文档简单步骤讲解
- 华为linux系统能用Cad么,华为平板能装cad画图吗 华为平板可以用cad软件吗?
- 斐波那契序列递归方法_斐波那契和卢卡斯序列
- 解决字符串存在\u6d4b\u8bd5\u5206\u7c7等中文汉字(乱码)(unicode码)
- 2022超nice的跨年烟花代码
- Yii2如何使用Yii:t()
- 对迅雷下载进行投毒的简单尝试
热门文章
- HTML中怎么设置超链接字体颜色和点击后的字体颜色
- Oracle Spacial(空间数据库)GEOMETRY示例
- 在一个静态方法内调用一个非静态成员为什么是非法的
- Hive启动 beeline 客户端失败问题解决
- 【凯子哥带你做高仿】“煎蛋”Android版的高仿及优化(三)——使用GreenDao实现本地Sqlite缓存
- Spring常见错误 - Bean构造注入报空指针异常
- 中职计算机网络技术专业教学标准,中等职业学校计算机网络技术专业教学标准.doc...
- 吴志祥php动态网页设计_PHP动态网页制作—毕业设计论文.doc
- Kaggle Days 来中国了,有人一起组队吗
- 从独步全球到缺乏创新,苹果正迷失在5G全面屏时代?