基于AQS的锁
锁分为独占锁和共享锁,它们的主要实现都是依靠AbstractQueuedSynchronizer,这个类只提供一系列公共的方法,让子类来调用。基于我了解不深,从这个类的属性,方法,和独占锁的获取方式去了解这个类。
AbstractQueuedSynchronizer的主要属性和方法:
| 属性/方法 | 含 义 |
| Thread exclusiveOwnerThread | 这个是AQS父类AbstractOwnableSynchronizer的属性,表示独占模式同步器的当前拥有者 |
| Node | 上面已经介绍过了,FIFO队列的基本单位 |
| Node head | FIFO队列中的头Node |
| Node tail | FIFO队列中的尾Node |
| int state | 同步状态,0表示未锁 |
| int getState() | 获取同步状态 |
| setState(int newState) | 设置同步状态 |
| boolean compareAndSetState(int expect, int update) | 利用CAS进行State的设置 |
| long spinForTimeoutThreshold = 1000L | 线程自旋等待的时间 |
| Node enq(final Node node) | 插入一个Node到FIFO队列中 |
| Node addWaiter(Node mode) | 为当前线程和指定模式创建并扩充一个等待队列 |
| void setHead(Node node) | 设置队列的头Node |
| void unparkSuccessor(Node node) | 如果存在的话,唤起Node持有的线程 |
| void doReleaseShared() | 共享模式下做释放锁的动作 |
| void cancelAcquire(Node node) | 取消正在进行的Node获取锁的尝试 |
| boolean shouldParkAfterFailedAcquire(Node pred, Node node) | 在尝试获取锁失败后是否应该禁用当前线程并等待 |
| void selfInterrupt() | 中断当前线程本身 |
| boolean parkAndCheckInterrupt() | 禁用当前线程进入等待状态并中断线程本身 |
| boolean acquireQueued(final Node node, int arg) | 队列中的线程获取锁 |
| tryAcquire(int arg) | 尝试获得锁(由AQS的子类实现它) |
| tryRelease(int arg) | 尝试释放锁(由AQS的子类实现它) |
| isHeldExclusively() | 是否独自持有锁 |
| acquire(int arg) | 获取锁 |
| release(int arg) | 释放锁 |
| compareAndSetHead(Node update) | 利用CAS设置头Node |
| compareAndSetTail(Node expect, Node update) | 利用CAS设置尾Node |
| compareAndSetWaitStatus(Node node, int expect, int update) | 利用CAS设置某个Node中的等待状态 |
可以看出这个类是一个链表结构,拥有head和tail,next,它的同步状态是通过int类型 state来表示的,0表示未获取,1表示获取,大于1表示重入数,compareAndSetState(int expect,int update)和spinForTimeoutThreshold是在多线程下插入节点到队列时保证快速和唯一正确的。compareAndSetState 和 setState 都是设置state的值,可以看源代码,发现compareAndSetState主要是获得锁,多线程竞争的时候使用,而setState则在锁重入的时候使用,有偏向锁的作用。
AQS是一个基于FIFO的队列的实现,有一个Node的内部类,主要属性如下如下:
| 属 性 | 定 义 |
| Node SHARED = new Node() | 表示Node处于共享模式 |
| Node EXCLUSIVE = null | 表示Node处于独占模式 |
| int CANCELLED = 1 | 因为超时或者中断,Node被设置为取消状态,被取消的Node不应该去竞争锁,只能保持取消状态不变,不能转换为其他状态,处于这种状态的Node会被踢出队列,被GC回收 |
| int SIGNAL = -1 | 表示这个Node的继任Node被阻塞了,到时需要通知它 |
| int CONDITION = -2 | 表示这个Node在条件队列中,因为等待某个条件而被阻塞 |
| int PROPAGATE = -3 | 使用在共享模式头Node有可能处于这种状态, 表示锁的下一次获取可以无条件传播 |
| int waitStatus | 0,新Node会处于这种状态 |
| Node prev | 队列中某个Node的前驱Node |
| Node next | 队列中某个Node的后继Node |
| Thread thread | 这个Node持有的线程,表示等待锁的线程 |
| Node nextWaiter | 表示下一个等待condition的Node |
获取独占锁的状态示意图如下:

基于AQS的锁的更多相关文章
- canal源码之BooleanMutex(基于AQS中共享锁实现)
在看canal源码时发现一个有趣的锁实现--BooleanMutex 这个锁在canal里面多处用到,相当于一个开关,比如系统初始化/授权控制,没权限时阻塞等待,有权限时所有线程都可以快速通过 先看它 ...
- JAVA并发-基于AQS实现自己的显示锁
一.了解什么是AQS 原文链接:http://www.studyshare.cn/blog-front/blog/details/1131 AQS是AbstractQueuedSynchronizer ...
- 老板让只懂Java基本语法的我,基于AQS实现一个锁
10 点整,我到了公司,又成为全组最后一个到的员工. 正准备刷刷手机摸摸鱼,看见老板神秘兮兮地走了过来. 老板:闪客呀,你写个工具,基于 AQS 实现一个锁,给咱们组其他开发用 我:哦好的 老板:你多 ...
- 聊聊ReentrantLock基于AQS的公平锁和非公平锁的实现区别
ReentrantLock锁的实现是基于AQS实现的,所以先简单说下AQS: AQS是AbstractQueuedSynchronizer缩写,顾名思义:抽象的队列同步器,它是JUC里面许多同步工具类 ...
- ReentrantLock是如何基于AQS实现的
ReentrantLock是一个可重入的互斥锁,基于AQS实现,它具有与使用 synchronized 方法和语句相同的一些基本行为和语义,但功能更强大. lock和unlock ReentrantL ...
- 基于AQS实现的Java并发工具类
本文主要介绍一下基于AQS实现的Java并发工具类的作用,然后简单谈一下该工具类的实现原理.其实都是AQS的相关知识,只不过在AQS上包装了一下而已.本文也是基于您在有AQS的相关知识基础上,进行讲解 ...
- RedLock.Net - 基于Redis分布式锁的开源实现
工作中,经常会遇到分布式环境中资源访问冲突问题,比如商城的库存数量处理,或者某个事件的原子性操作,都需要确保某个时间段内只有一个线程在访问或处理资源. 因此现在网上也有很多的分布式锁的解决方案,有数据 ...
- 关于AQS——独占锁的相关方法(一)
一.序言 Lock接口是juc包下一个非常好用的锁,其方便和强大的功能让他成为synchronized的一个很好的替代品. 我们常用的一个Lock的实现类(好像也是唯一一个只实现了Lock接口的类) ...
- 如何基于String实现锁?
在某些时候,我们可能想基于字符串做一些事情,比如:针对同一用户的并发同步操作,使用锁字符串的方式实现比较合理.因为只有在相同字符串的情况下,并发操作才是不被允许的. 因为String 类型的变量赋值是 ...
随机推荐
- SQL2005语句实现行转列,列转行
在做报表时,经常需要将数据表中的行转列,或者列转行,如果不知道方法,你会觉得通过SQL语句来实现非常难.这里,我将使用pivot和unpivot来实现看似复杂的功能.这个功能在sql2005及以上版本 ...
- ubuntu 常见问题
1.problem 1 用apt-get安装时,提示:E could not get lock /vaa/lib/dpkg/lock -open等 reasons :可能是由于上次使用apt-get ...
- RabbitMQ、Rdis
RabbitMQ RabbitMQ:官方网址:http://www.rabbitmq.com/ Install Erlang # rpm -ivh erlang-18.3-1.el6.x86_64.r ...
- Net操作Excel(终极方法NPOI)
NPOI 待学习 http://www.cnblogs.com/stone_w/archive/2012/08/02/2620528.html
- 一个非常牛比的前端google插件
WEB前端助手(FeHelper) 用了都说好,嘻嘻
- 用git管理自己读的书
福昕阅读器,可以方便地做书签和备注.使用git去管理图书和示例代码,一方面能够很好地保存这些资料,方便查找:另外一方面,无论在家,还是在公司,都能很好地同步自己学习的进度. 福昕阅读器5(视图--&g ...
- Windows Driver Frameworks
MSDN原文:https://msdn.microsoft.com/zh-cn/library/windows/hardware/ff557565(v=vs.85).aspx
- 拥抱高效、拥抱 Bugtags 之来自用户的声音 2
小编按:这是一篇 Bugtags 用户来稿,主要是介绍了使用 Bugtags 前后对测试及解决 Bug 所带来的变化,感谢单车娱乐 App 工程师 - 李斌同学对 Bugtags 的信赖和支持.小编在 ...
- Mysql的视图、存储过程、函数、索引全解析
视图是查询命令结果构成的一个虚拟表(非真实存在),其本质是[根据SQL语句获取动态的数据集,并为其命名],用户使用时只需使用[名称]即可获取结果集合,并可以当作表来查询使用. 1创建视图 --格式:C ...
- Oracle Merge备忘示例
Oracle的merge语法非常实用,用于Insert.Update判断情况.以下是自己书写的一个示例,以免时间长了语法形式忘记了. MERGE INTO T_FR_GUOSZX T USING (S ...