锁分为独占锁和共享锁,它们的主要实现都是依靠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】Infobright和mysql数据入库性能测试

    产生测试文件 测试文件部分内容如下: 产生测试文件代码: package foo; import java.io.File; import java.io.FileWriter; import jav ...

  2. WCF部署于IIS使用的几个问题总结

    Q:wcf 远程服务器返回错误: (405) 不允许的方法. A: new SqlServerOperateClient("BasicHttpBinding_ISqlServerOperat ...

  3. Map以及Set的遍历(EntrySet方法,补充enumeration和Iterator的区别)

    public void mearge(Map map) { Map returnMap = new HashMap<>(); // 转换为Entry Set<Map.Entry< ...

  4. x64 PL/SQL 连接 Oralce 提示 Could not initialize oci.dll

    在 x64 的 Win10 上重新安装了 Oralce 后,通过 PL/SQL 连接数据库时,提示如下错误信息 环境 windows7 64bit Oracle win64 11gR2 PL/SQL ...

  5. myBatis之事务管理

    1. myBatis单独使用时,使用SqlSession来处理事务: public class MyBatisTxTest { private static SqlSessionFactory sql ...

  6. jquery 中post 、get的同步问题

    jquery 中post .get的同步问题 解决方法1: 在全局设置: $.ajaxSetup({ async : false }); 然后再使用post或get方法 $.get("reg ...

  7. Esfog_UnityShader教程_遮挡描边(原理篇)

    咳咳,有段时间没有更新了,最近有点懒!把不少精力都放在C++身上了.闲言少叙,今天要讲的可和之前的几篇有所不同了,这次是一个次综合应用.这篇内容中与之前不同主要体现在下面几点上. 1.之前我们写的都是 ...

  8. OpenSSLKey

    http://www.jensign.com/opensslkey/opensslkey.cs //************************************************** ...

  9. 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 ...

  10. .net工作准备系列--01前言

    注:学习参考朱毅编著的进入IT名企必读200题. 内容重在自我学习与巩固. 前言: 章节划分 01应聘须知 02基础知识(重点) 03进阶知识 04重点应用(aspnet第一部分) 04重点应用(as ...