1.  前言

Java中好多地方用到AbstractQueuedSynchronizer(PS:简称AQS),比如ReentrantLock、线程池,这部分在面试的时候也经常被问到,今天以ReentrantLock为例,通过源码来加深对AQS的理解

2.  lock

通常,我们的用法是这样的:

那么lock(),unlock()到底做了什么,我们并不知晓,接下来一步一步揭开她的神秘面纱

2.1.  lock

可以看到,ReentrantLock默认是NonfairSync(非公平锁)

2.2.  NonfairSync

可以看到,首先判断同步状态是否是0,如果是0则临界资源没有被占用,并且将状态设为1,当前线程获得这个资源,可以访问;否则,调用acquire(1)方法尝试获取资源的访问控制权。

2.3.  tryAcquire

尝试再获取一次

如果当前同步状态是0,则跟之前相同,将状态置为1,当前线程获得访问权,返回true

如果当前资源的所有者线程就是当前线程,则状态加1,当前线程仍然获得访问权,返回true

如果以上情况都不是(PS:资源被别的线程占用着),则返回false

2.4.  acquireQueued

如果上一步tryAcquire方法返回false,则继续调用acquireQueued方法将线程添加到队列中(PS:链表的尾部)

在添加到链表之前,先封装成Node对象

将当前线程构造成Node对象,节点的模式是排它的,然后将其加到链表的尾部(或是说叫队列),最后将该结点返回

这里有两个特殊的节点:等待队列的头结点 和 等待队列的尾结点

接下来,将刚才构造的节点加到队列中

如果当前节点的前驱节点是头结点(head),并且当前节点再次尝试获取资源(tryAcquire方法),恰好成功了,于是皆大欢喜

如果当前节点的前驱节点既不是head,而且当前节点也没有抢占到资源,则循环直到前驱节点的状态变成SIGNAL,则挂起当前线程

3.  unlock

如果资源的所有者线程不是当前线程的话,则抛出异常

如果当前资源同步状态减1恰好是0,则成功释放,同步状态置为0,资源所有者线程置为null,唤醒head的后继节点

4.  小结

加锁

1、默认非公平锁(PS:当前线程不是直接加到等待队列中,而是先尝试获取一次,如果不成功则加到队列中,在加的时候还会尝试一次)

2、临街资源有一个同步状态,0表示当前没有线程占用,则可以直接可以获取到资源(加锁成功)

3、如果资源所有者线程就是当前线程,则状态加1,仍然可以获得锁

3、加锁成功以后,将同步状态置为1,资源所有者线程置为当前线程

4、不成功,则封装成Node加入到等待队列(链表)中,此时,还会像前面一样再尝试(抢占)一次

5、抢占不成功,加到等待队列中,线程挂起

解锁

1、资源所有者线程不是当前线程,则抛异常

2、唤醒下一个结点

AbstractQueuedSynchronizer源码分析(ReentrantLock锁的实现)的更多相关文章

  1. Java并发系列[2]----AbstractQueuedSynchronizer源码分析之独占模式

    在上一篇<Java并发系列[1]----AbstractQueuedSynchronizer源码分析之概要分析>中我们介绍了AbstractQueuedSynchronizer基本的一些概 ...

  2. AbstractQueuedSynchronizer源码分析

    AbstractQueuedSynchronizer源码分析 前提 AQS(java.util.concurrent.locks.AbstractQueuedSynchronizer)是并发编程大师D ...

  3. Java并发系列[3]----AbstractQueuedSynchronizer源码分析之共享模式

    通过上一篇的分析,我们知道了独占模式获取锁有三种方式,分别是不响应线程中断获取,响应线程中断获取,设置超时时间获取.在共享模式下获取锁的方式也是这三种,而且基本上都是大同小异,我们搞清楚了一种就能很快 ...

  4. Java并发系列[4]----AbstractQueuedSynchronizer源码分析之条件队列

    通过前面三篇的分析,我们深入了解了AbstractQueuedSynchronizer的内部结构和一些设计理念,知道了AbstractQueuedSynchronizer内部维护了一个同步状态和两个排 ...

  5. 鸿蒙内核源码分析(互斥锁篇) | 比自旋锁丰满的互斥锁 | 百篇博客分析OpenHarmony源码 | v27.02

    百篇博客系列篇.本篇为: v27.xx 鸿蒙内核源码分析(互斥锁篇) | 比自旋锁丰满的互斥锁 | 51.c.h .o 进程通讯相关篇为: v26.xx 鸿蒙内核源码分析(自旋锁篇) | 自旋锁当立贞 ...

  6. 鸿蒙内核源码分析(自旋锁篇) | 当立贞节牌坊的好同志 | 百篇博客分析OpenHarmony源码 | v26.02

    百篇博客系列篇.本篇为: v26.xx 鸿蒙内核源码分析(自旋锁篇) | 当立贞节牌坊的好同志 | 51.c.h .o 进程通讯相关篇为: v26.xx 鸿蒙内核源码分析(自旋锁篇) | 当立贞节牌坊 ...

  7. [源码分析]ReentrantLock & AbstractQueuedSynchronizer & Condition

    首先声明一点: 我在分析源码的时候, 把jdk源码复制出来进行中文的注释, 有时还进行编译调试什么的, 为了避免和jdk原生的类混淆, 我在类前面加了"My". 比如把Reentr ...

  8. 【JDK】JDK源码分析-ReentrantLock

    概述 在 JDK 1.5 以前,锁的实现只能用 synchronized 关键字:1.5 开始提供了 ReentrantLock,它是 API 层面的锁.先看下 ReentrantLock 的类签名以 ...

  9. 多线程之美5一 AbstractQueuedSynchronizer源码分析<一>

    AQS的源码分析 目录结构 1.什么是CAS ? 2.同步器类结构 3.CLH同步队列 4.AQS中静态内部类Node 5.方法分析 ​ 5.1.acquire(int arg ) ​ 5.2.rel ...

  10. Java并发包源码学习之AQS框架(四)AbstractQueuedSynchronizer源码分析

    经过前面几篇文章的铺垫,今天我们终于要看看AQS的庐山真面目了,建议第一次看AbstractQueuedSynchronizer 类源码的朋友可以先看下我前面几篇文章: <Java并发包源码学习 ...

随机推荐

  1. ES6躬行记(15)——箭头函数和尾调用优化

    一.箭头函数 箭头函数(Arrow Function)是ES6提供的一个很实用的新功能,与普通函数相比,不但在语法上更为简洁,而且在使用时也有更多注意点,下面列出了其中的三点: (1)由于不能作为构造 ...

  2. sqlzoo:using group by and having

    For each continent show the number of countries: SELECT continent, COUNT(name) FROM world GROUP BY c ...

  3. maven项目如何手动打包

    1.确定打包对象:dubbo-admin 2.进入打包对象目录,复制目录路径(D:\H\dubbox-master\dubbo-admin). 可以看到该对象为典型的maven目录,此时没有“targ ...

  4. PHP CURL获取页面内容输出例子

    使用PHP curl获取页面内容或提交数据,有时候希望返回的内容作为变量储存,而不是直接输出.这个时候就必需设置curl的CURLOPT_RETURNTRANSFER选项为1或true. 1.curl ...

  5. Php中文件下载功能实现超详细流程分析

    浏览器发送一个请求,请求访问服务器中的某个网页(如:down.php),该网页的代码如下   客户端从服务端下载文件的流程分析: 浏览器发送一个请求,请求访问服务器中的某个网页(如:down.php) ...

  6. position属性sticky和fixed的区别比较

    position属性之fixed fixed总是以body为定位时的对象,总是根据浏览器窗口来进行元素的定位,通过left,right,top,bottom属性进行定位. <!DOCTYPE h ...

  7. CommonsChunkPlugin

    CommonsChunk 插件的作用就是提取代码中的公共代码,然后将公共模块打包到一个独立的文件中,以便在其它的入口和模块中使用,原理就是把多个入口共同的依赖都给定义成一个新入口 多种打包情况: 单一 ...

  8. 常用输入的js验证

    身份证 var idnub = document.getElementById('idnub').value; if(idnub.length > 1){ var reg = /(^\d{15} ...

  9. python编程从入门到实战1-3章

    print('hellow world') """ 多行注释"""#大小写print('i love you')mssage='hellow ...

  10. PDF转换成Word,ppt转换成word

    pdf与word我没找到直接转换的方式,不过可以用间接方式嘛! pdf ==>picture ==>word!ppt转word的原理也是先把ppt转成图片,再把图片插入word! 先准备好 ...