ReentrantLock的底层实现机制 AQS
ReentrantLock的底层实现机制是AQS(Abstract Queued Synchronizer 抽象队列同步器)。AQS没有锁之类的概念,它有个state变量,是个int类型,为了好理解,可以把state当成锁,AQS围绕state提供两种基本操作“获取”和“释放”,有条双向队列存放阻塞的等待线程。AQS的功能可以分为独占和共享,ReentrantLock实现了独占功能(每次只能有一个线程能持有锁)。
在ReentrantLock类中,有一个内部类Sync,它继承了AQS,但是将lock()方法定义为抽象方法,由子类负责实现(采用的是模板方法的设计模式)。
abstract void lock();
Sync分为公平锁和非公平锁,所以又有FairSync和NonfairSync继承Sync。
ReentrantLock的默认构造实现是非公平锁,也就是线程获取锁的顺序和调用lock的顺序无关。所有线程同时去竞争锁,线程发出请求后立即尝试获取锁,如果有可用的则直接获取锁,失败才进入等待队列。

在非公平锁NonfairSync中,

线程只要有机会就抢占,才不管排队的事。直接尝试将state修改为1,如果修改state失败,则和公平锁一样,调用acquire。(乐观锁的思想)
在公平锁FairSync中,线程去竞争一个锁,可能成功也可能失败。成功就直接持有资源,不需要进入队列;失败的话进入队列阻塞,等待唤醒后再尝试竞争锁。

首先尝试着去获取锁,如果state的当前状态为0,且没有前继线程在等待,表明没有线程占用,此时可以获得锁,然后设置当前线程为独占线程,并返回true,此时不会调用acquireQueued()方法(&& : 只有当&&左边程序为真,才会执行&&右边的程序,否者不会执行后面的),且不会执行selfInterrupt()方法。

相反,如果获取锁失败,则会执行
acquireQueued(addWaiter(Node.EXCLUSIVE), arg)
该首先会将当前线程包装成一个Node,插入到双向队列尾

标记1判断该Node的前继节点p,如果前一个节点正好是head,表示自己排在第一位,可以马上调用tryAcquire尝试。如果获取成功就简单了,直接修改自己为head。这步是实现公平锁的核心。标记2是线程没有获取到锁的情况(当前线程没有排到第一位),这个时候,线程可能等着下一次获取,也可能不想要了,Node变量waitState描述了线程的等待状态。

shouldParkAfterFailedAcquire()方法会根据前一个节点的waitStatus作出抉择,如果前节点状态是SIGNAL,则当前线程需要阻塞。

如果线程需要阻塞,则由parkAndCheckInterrupt()方法进行操作。LockSupport和cas一样,最终使用UNSAFE调用Native方法实现线程阻塞(park和unpark方法作用类似于wait和notify)

释放锁:
public void unlock() {
sync.release(1);
}
头节点是获取锁的线程,如果tryRelease()释放成功,会将头节点先移出队列,再通知后面的节点获取锁

如果有后继节点,则唤醒线程,重新尝试去获取锁。

ReentrantLock的底层实现机制 AQS的更多相关文章
- ReentrantLock 源码分析以及 AQS (一)
前言 JDK1.5 之后发布了JUC(java.util.concurrent),用于解决多线程并发问题.AQS 是一个特别重要的同步框架,很多同步类都借助于 AQS 实现了对线程同步状态的管理. A ...
- <转>ASP.NET学习笔记之理解MVC底层运行机制
ASP.NET MVC架构与实战系列之一:理解MVC底层运行机制 今天,我将开启一个崭新的话题:ASP.NET MVC框架的探讨.首先,我们回顾一下ASP.NET Web Form技术与ASP.NET ...
- 【Spark 深入学习 04】再说Spark底层运行机制
本节内容 · spark底层执行机制 · 细说RDD构建过程 · Job Stage的划分算法 · Task最佳计算位置算法 一.spark底层执行机制 对于Spark底层的运行原理,找到了一副很好的 ...
- .net core系列之《从源码对Configuration的底层运行机制进行分析》
通过对Configuration源代码的分析从而来自定义一个配置数据源 1.用反编译工具来看看AddJsonFile()这个方法究竟干了什么,源代码如下: public static IConfigu ...
- Spring AOP简介与底层实现机制——动态代理
AOP简介 AOP (Aspect Oriented Programing) 称为:面向切面编程,它是一种编程思想.AOP 是 OOP(面向对象编程 Object Oriented Programmi ...
- Spring的底层实现机制
Spring的底层实现机制是通过Demo4j+java反射机制实现的. 使用demo4j来解析xml,使用反射机制实例化bean.
- AQS:Java 中悲观锁的底层实现机制
介绍 AQS AQS(AbstractQueuedSynchronizer)是 Java 并发包中,实现各种同步组件的基础.比如 各种锁:ReentrantLock.ReadWriteLock.Sta ...
- 深入浅出 Java Concurrency 锁机制 : AQS
转载:http://www.blogjava.net/xylz/archive/2010/07/06/325390.html 在理解J.U.C原理以及锁机制之前,我们来介绍J.U.C框架最核心也是最复 ...
- ReentrantLock的实现原理及AQS和CAS
AQS,即AbstractQueuedSynchronizer, 队列同步器,它是多线程访问共享资源的同步器框架,Java中的ReentrantLock/Semaphore/CountDownLatc ...
随机推荐
- 微软发布新版 Skype Linux 客户端
导读 前两天,微软说要给Linux 用户带来一个令人兴奋的新闻,今天,这个新闻来了.它刚刚为 Linux 发布了一个新的 Skype 客户端.此次发布,微软为 Linux 带来的 Skype 客户端与 ...
- hdu1059(多重背包优化)
使用一种二进制的优化, 可以完美的解决这题,<背包九讲>中说的非常好 但是还有一种线性复杂的算法. 应该算是该题很巧妙的解法 ;i++) { ;l--) { ) continue; ;k& ...
- Ubuntu 16.04 安装 Gnome 桌面环境
个人博客链接:Ubuntu 16.04 安装 Gnome 桌面环境
- 170419、Centos7下完美安装并配置mysql5.6
首先跟各位说声抱歉,原计划说每天一篇博文,最近由于实在太忙,封闭式开发一个项目,没有时间写博文,望大家见谅!!! 由于公司要搭建分布式服务,我把最近我所用到或者学习的技术或者遇到的问题跟大家分享一下! ...
- Python全栈day13(作业讲解字典嵌套实现用户输入地址信息添加及查看)
要求: 列出字典对应节点名称,根据用户输入可以添加节点,查看节点等功能,这里以地址省-市-县等作为列子,此题熟悉字典嵌套功能 vim day13-16.py db = {} path = [] whi ...
- 多线程入门-第六章-线程的调度与控制之join
/* 线程合并:将指定的线程加入到当前线程,可以将两个交替执行的线程合并为顺序执行的线程,即单线程. 如在B线程中调用了A的join方法,则线程A执行完后,才会执行线程B. */ public cla ...
- 【JVM】线上应用故障排查
高CPU占用 一个应用占用CPU很高,除了确实是计算密集型应用之外,通常原因都是出现了死循环. 根据top命令,发现PID为28555的Java进程占用CPU高达200%,出现故障. 通过ps aux ...
- golang几种post方式
用golang进行http请求类型多了,总结备忘一下. 1.普通的post\get请求 var r http.Request r.ParseForm() r.Form.Add("uuid&q ...
- Vuex、axios以及跨域请求处理
一.Vuex 1.介绍 vuex是一个专门为Vue.js设计的集中式状态管理架构. 对于状态,我们把它理解为在data中需要共享给其他组件使用的部分数据. Vuex和单纯的全局对象有以下不同: 1. ...
- oracle编程艺术--runstst工具
runstats工具是< oracle database 9i/10g/11g编程艺术 深入数据库体系结构>作者写的一个统计性能工具,能对做同一件事的两个方法进行比较,得到孰优孰劣的结果. ...