锁分为独占锁和共享锁,它们的主要实现都是依靠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的锁的更多相关文章

  1. canal源码之BooleanMutex(基于AQS中共享锁实现)

    在看canal源码时发现一个有趣的锁实现--BooleanMutex 这个锁在canal里面多处用到,相当于一个开关,比如系统初始化/授权控制,没权限时阻塞等待,有权限时所有线程都可以快速通过 先看它 ...

  2. JAVA并发-基于AQS实现自己的显示锁

    一.了解什么是AQS 原文链接:http://www.studyshare.cn/blog-front/blog/details/1131 AQS是AbstractQueuedSynchronizer ...

  3. 老板让只懂Java基本语法的我,基于AQS实现一个锁

    10 点整,我到了公司,又成为全组最后一个到的员工. 正准备刷刷手机摸摸鱼,看见老板神秘兮兮地走了过来. 老板:闪客呀,你写个工具,基于 AQS 实现一个锁,给咱们组其他开发用 我:哦好的 老板:你多 ...

  4. 聊聊ReentrantLock基于AQS的公平锁和非公平锁的实现区别

    ReentrantLock锁的实现是基于AQS实现的,所以先简单说下AQS: AQS是AbstractQueuedSynchronizer缩写,顾名思义:抽象的队列同步器,它是JUC里面许多同步工具类 ...

  5. ReentrantLock是如何基于AQS实现的

    ReentrantLock是一个可重入的互斥锁,基于AQS实现,它具有与使用 synchronized 方法和语句相同的一些基本行为和语义,但功能更强大. lock和unlock ReentrantL ...

  6. 基于AQS实现的Java并发工具类

    本文主要介绍一下基于AQS实现的Java并发工具类的作用,然后简单谈一下该工具类的实现原理.其实都是AQS的相关知识,只不过在AQS上包装了一下而已.本文也是基于您在有AQS的相关知识基础上,进行讲解 ...

  7. RedLock.Net - 基于Redis分布式锁的开源实现

    工作中,经常会遇到分布式环境中资源访问冲突问题,比如商城的库存数量处理,或者某个事件的原子性操作,都需要确保某个时间段内只有一个线程在访问或处理资源. 因此现在网上也有很多的分布式锁的解决方案,有数据 ...

  8. 关于AQS——独占锁的相关方法(一)

    一.序言 Lock接口是juc包下一个非常好用的锁,其方便和强大的功能让他成为synchronized的一个很好的替代品. 我们常用的一个Lock的实现类(好像也是唯一一个只实现了Lock接口的类) ...

  9. 如何基于String实现锁?

    在某些时候,我们可能想基于字符串做一些事情,比如:针对同一用户的并发同步操作,使用锁字符串的方式实现比较合理.因为只有在相同字符串的情况下,并发操作才是不被允许的. 因为String 类型的变量赋值是 ...

随机推荐

  1. mysql-bin引起mysql不能启动

    日志提示无法找到mysql-bin.000005这个文件 原因是我把其删除了,而在mysql-bin.index文件中却还有mysql-bin.000005的记录,因此启动失败了 解决: cd /va ...

  2. https 双向证书

    一:服务器端 1.首先需要配置站点的SSl证书 打开Nginx安装目录下conf目录中的nginx.conf文件 找到    # HTTPS server     #     #server {   ...

  3. ashx文件不能使用DAL和Model的解决办法

    好久没有写web程序了,今天在写web程序时,发现一个问题,在ashx文件中,已经using了DAL和Model命名空间,而且引用中也引用了程序集,可是还报错:未能找到类型或命名空间"Mod ...

  4. [asp.net]c# winform打印类

    using System; using System.Collections.Generic; using System.Text; using System.Windows.Forms; using ...

  5. 转mysql 多表 update sql语句总结

    mysql 多表 update 有几种不同的写法. 假定我们有两张表,一张表为Product表存放产品信息,其中有产品价格列Price:另外一张表是ProductPrice表,我们要将ProductP ...

  6. firefox火狐浏览器过滤广告插件:Adblock Plus

    firefox火狐浏览器过滤广告插件:Adblock Plus

  7. nyoj 142, poj 1039 ,hdu 1454 管道问题

    http://acm.nyist.net/JudgeOnline/problem.php?pid=142 第一道解析几何问题,比较纠结,主要是几个解析几何的基本操作,包括求两线段的叉积,判断左右方向, ...

  8. Linux基础之常用命令(1)

    一 linux命令的格式 1.命令  [选项]  [参数] ls  list    显示目录下内容 ①  命令名称:ls 命令英文原意:list 命令所在路径:/bin/ls 执行权限:所有用户 功能 ...

  9. flume整合kafka

    # Please paste flume.conf here. Example: # Sources, channels, and sinks are defined per # agent name ...

  10. win7双系统安装ubuntu并配置常用软件

    首先在win7下磁盘清理出来空间具体方法找度娘就行了. 下面开始准备安装: 1.下载easyBCD 2.打开:添加新条目--NeoGub--安装 3.点击配置  修改menu.lst title In ...