基于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 类型的变量赋值是 ...
随机推荐
- 【mysql】Infobright和mysql数据入库性能测试
产生测试文件 测试文件部分内容如下: 产生测试文件代码: package foo; import java.io.File; import java.io.FileWriter; import jav ...
- WCF部署于IIS使用的几个问题总结
Q:wcf 远程服务器返回错误: (405) 不允许的方法. A: new SqlServerOperateClient("BasicHttpBinding_ISqlServerOperat ...
- Map以及Set的遍历(EntrySet方法,补充enumeration和Iterator的区别)
public void mearge(Map map) { Map returnMap = new HashMap<>(); // 转换为Entry Set<Map.Entry< ...
- x64 PL/SQL 连接 Oralce 提示 Could not initialize oci.dll
在 x64 的 Win10 上重新安装了 Oralce 后,通过 PL/SQL 连接数据库时,提示如下错误信息 环境 windows7 64bit Oracle win64 11gR2 PL/SQL ...
- myBatis之事务管理
1. myBatis单独使用时,使用SqlSession来处理事务: public class MyBatisTxTest { private static SqlSessionFactory sql ...
- jquery 中post 、get的同步问题
jquery 中post .get的同步问题 解决方法1: 在全局设置: $.ajaxSetup({ async : false }); 然后再使用post或get方法 $.get("reg ...
- Esfog_UnityShader教程_遮挡描边(原理篇)
咳咳,有段时间没有更新了,最近有点懒!把不少精力都放在C++身上了.闲言少叙,今天要讲的可和之前的几篇有所不同了,这次是一个次综合应用.这篇内容中与之前不同主要体现在下面几点上. 1.之前我们写的都是 ...
- OpenSSLKey
http://www.jensign.com/opensslkey/opensslkey.cs //************************************************** ...
- ubuntu graphic cannot display
1.ubuntu resuce mode 2.mount -o,remount,rw /dev/sda6 / 3.dhclient eth0 4.apt-get update apt-get inst ...
- .net工作准备系列--01前言
注:学习参考朱毅编著的进入IT名企必读200题. 内容重在自我学习与巩固. 前言: 章节划分 01应聘须知 02基础知识(重点) 03进阶知识 04重点应用(aspnet第一部分) 04重点应用(as ...