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 ...
随机推荐
- Android音视频学习第7章:使用OpenSL ES进行音频解码
/* * *这里使用了transcode-1.1.7对wav文件进行解码.然后使用opensl es进行播放 * */ //用到的变量和结构体 WAV wav; //wav文件指针 SLObjectI ...
- ios开发之--PDF文件生成
写项目的时候,碰到一个需求,就是在手机端根据指定的文件内容生成PDF文件,并可以保存到手机上,因为以前只是听说过,没有真正的去了解过这个需求,通过查阅资料,可以实现这个功能,话不多说,代码如下: -( ...
- 关于recycler遇到的问题
1.//设置recyclerView不能点击myLayoutManager.setScrollEnabled(false);class MyLayoutManager extends LinearLa ...
- Spring学习笔记--使用Spring基于Java的配置
我们需要使用@Component注解来定义一个配置类,在配置类中我们定义Bean: package com.moonlit.myspring; import org.springframework.c ...
- Jenkins publish over ssh 上传 文件夹 配置方式
需要把编译后 目录下的 lib文件夹下的jar包都上传到服务器上 1.配置 2.完成截图 3.服务器截图 注意: 真实脚本 建议写 全路径 注意:多条命令时 添加 英文分号
- Linux内核态、用户态简介与IntelCPU特权级别--Ring0-3
一.现代操作系统的权限分离: 现代操作系统一般都至少分为内核态和用户态.一般应用程序通常运行于用户态,而当应用程序调用系统调用时候会执行内核代码,此时会处于内核态.一般的,应用程序是不能随便进入内核态 ...
- Fragment、FragmentTabHost以及RadioGroup框架
package com.dotfive.chuanbang.activity; import test.Fragment1; import test.Fragment1.OnBackListener; ...
- 使用jquery修改标题$("title").html("标题")应注意的问题
使用jquery修改标题$("title").html("标题")应注意的问题: 如果修改后的标题和原标题一致,jquery会跳过该操作,这种情况再从其他页面回 ...
- angular4 常用pipe管道
angular中的pipe是用来对输入的数据进行处理,如大小写转换.数值和日期格式化等. 常用的pipe有 1. 大小写转换 <p>{{str | uppercase}}</p> ...
- SVN备份及恢复
一,SVN备份 svnadmin dump /data/svn/blzfmima/ > /tmp/full.svn.bak 其中/data/svn/blzfmima/为svn文件夹,导出成一个备 ...