Java中关于AbstractQueuedSynchronizer的入门(一)
备注:博文仅仅是学习过程中的零散记录,后期整理。
AbstractQueuedSynchronizer的简单介绍可以网上搜索,简单了解字段作用。
示例代码,分析获取锁的过程:
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock; public class AQS {
public static void main(String[] args) { Lock lock = new ReentrantLock(); lock.lock(); // do something lock.unlock(); } }
调用lock方法,然后间接调用:
/**
* Sync object for non-fair locks
*/
static final class NonfairSync extends Sync {
private static final long serialVersionUID = 7316153563782823691L; /**
* Performs lock. Try immediate barge, backing up to normal
* acquire on failure.
*/
final void lock() {
if (compareAndSetState(0, 1))//更新state的状态值,state是用来记录获取锁的情况。state=0的话则锁没有人获取,当大于0时候表示锁被获取。重入次数。
setExclusiveOwnerThread(Thread.currentThread()); //AQS的exclusiveOwnerThread成员,记录当前获取锁的线程
else
acquire(1);
} protected final boolean tryAcquire(int acquires) {
return nonfairTryAcquire(acquires);
}
}
调用如上代码的lock方法,其中的compareAndSetState调用底层操作系统的CAS方法,是一个原子操作。到此就完成了获取锁。
接下来看看重入锁申请过程,java.util.concurrent.locks.ReentrantLock.Sync.nonfairTryAcquire(int):
/**
* Performs non-fair tryLock. tryAcquire is
* implemented in subclasses, but both need nonfair
* try for trylock method.
*/
final boolean nonfairTryAcquire(int acquires) {
final Thread current = Thread.currentThread(); //当获取重入锁时候,判断当前线程和之前申请锁的线程是否是一个?如果不是一个的话则直接返回false
int c = getState();
if (c == 0) { //第一次获取锁时,state为0
if (compareAndSetState(0, acquires)) {
setExclusiveOwnerThread(current);
return true;
}
}
//如果不是第一次的话,则重入锁
else if (current == getExclusiveOwnerThread()) {
int nextc = c + acquires; //acquires参数每一次获取锁时候,参数acquires都为1,代表依次获取锁。nextc是当前一共获取锁的次数
if (nextc < 0) // overflow ,重入次数过多,导致大于Int最大值溢出,抛异常
throw new Error("Maximum lock count exceeded");
setState(nextc);//更新state状态值
return true; //获取锁成功
}
return false;
}
接下来看看释放锁的过程,java.util.concurrent.locks.ReentrantLock.Sync.tryRelease(int):
//unlock最终调用这个方法释放锁
protected final boolean tryRelease(int releases) {
int c = getState() - releases; //判断state的值,释放锁进行一次减1操作
if (Thread.currentThread() != getExclusiveOwnerThread())//判断释放锁的线程和当初获取锁的线程是否是一个线程,不是的话则抛异常
throw new IllegalMonitorStateException();
boolean free = false;
if (c == 0) {//如果锁已经彻底释放,则将获取锁的线程设置为null
free = true;
setExclusiveOwnerThread(null);
}
setState(c);//更新state的状态
return free;
}
重入锁的释放同上。
Java中关于AbstractQueuedSynchronizer的入门(一)的更多相关文章
- Java中关于AbstractQueuedSynchronizer的入门(二)
AQS是一个同步器的基础类,里面的关键字段: //如下关键字段都是volatile类型 /** * Head of the wait queue, lazily initialized. Except ...
- Java中的IO流 - 入门篇
前言 大家好啊,我是汤圆,今天给大家带来的是<Java中的IO流-入门篇>,希望对大家有帮助,谢谢 由于Java的IO类有很多,这就导致我刚开始学的时候,感觉很乱,每次用到都是上网搜,结果 ...
- Java中的集合List - 入门篇
前言 大家好啊,我是汤圆,今天给大家带来的是<Java中的集合List - 入门篇>,希望对大家有帮助,谢谢 简介 说实话,Java中的集合有很多种,但是这里作为入门级别,先简单介绍第一种 ...
- Java中的映射Map - 入门篇
前言 大家好啊,我是汤圆,今天给大家带来的是<Java中的映射Map - 入门篇>,希望对大家有帮助,谢谢 简介 前面介绍了集合List,这里开始简单介绍下映射Map,相关类如下图所示 正 ...
- Java中的集合Set - 入门篇
前言 大家好啊,我是汤圆,今天给大家带来的是<Java中的集合Set - 入门篇>,希望对大家有帮助,谢谢 简介 前面介绍了集合List,映射Map,最后再简单介绍下集合Set,相关类如下 ...
- Java中Redis的简单入门
1.下载redis服务器端程序: 在redis.io官网完成服务器端程序下载:可下载安装版或解压版,此处我下载的是解压版,下载完成后解压. 2.配置redis密码,开启redis服务端 在redis. ...
- Java中Redis简单入门
Redis是一个开源的,先进的 key-value 存储可用于构建高性能,可扩展的 Web 应用程序的解决方案. Redis官方网网站是:http://www.redis.io/,如下: Redis ...
- 【JAVA零基础入门系列】Day5 Java中的运算符
运算符,顾名思义就是用于运算的符号,比如最简单的+-*/,这些运算符可以用来进行数学运算,举个最简单的栗子: 已知长方形的长为3cm,高为4cm,求长方形的面积. 好,我们先新建一个项目,命名为Rec ...
- 【JAVA零基础入门系列】Day9 Java中的那个大数值
什么是大数值?用脚趾头想也知道,当然是"大"的数值(233).Java中有两个用于表示大数值的类,BigInteger和BigDecimal,那到底能表示多大的数值呢?理论上,可以 ...
随机推荐
- Linux 强制安装 rpm 包
Linux 正常安装 rpm 的命令是: rpm -ivh xxx.rpm 重复安装时需加属性: 软件包重复安装将会失败,若仍需要安装必须加 --replacepkgs 属性 软件包的某个文件已在安装 ...
- Oracle字符串函数
Oracle字符串函数 平常我们用Oracle主要有两种字符串类型1.char始终为固定的长度,如果设置了长度小于char列的值,则Oracle会自动用空格填充的.当比较char时,Oracle用空格 ...
- [翻译]EntityFramework Core 2.2 发布
原文来源 TechViews 今天我们将推出EF Core 2.2的最终版本,以及ASP.NET Core 2.2和.NET Core 2.2 .这是我们的开源和跨平台对象数据库映射技术的最新版本. ...
- WPF 使用 Direct2D1 画图入门
本文来告诉大家如何在 WPF 使用 D2D 画图. 本文是一个系列 WPF 使用 Direct2D1 画图入门 WPF 使用 Direct2D1 画图 绘制基本图形 WPF 使用 SharpDX WP ...
- Java面试总结(集合、spring)
Java 集合框架简介 Java Collections Framework,最开始也是一个开源框架,后来被收录到JDK中 所谓的集合,就是能存放多个数据元素的容器,在Java中原生的容器是数组 数组 ...
- Java--实现单点登录
1 什么是单点登陆 单点登录(Single Sign On),简称为 SSO,是目前比较流行的企业业务整合的解决方案之一.SSO的定义是在多个应用系统中,用户只需要登录一次就可以访问所有相互信任的应用 ...
- coffee.js
( ) ( ( ) ) ( ( ( ) ) ) ########################## ############################ #################### ...
- JS数组迭代方法
先说 every()和 some(),它们都用于查询数组中的项是否满足某个条件. every(): var numbers = [1,2,3,4,5,4,3,2,1]; var everyResult ...
- vue2.0 element-ui中el-upload的before-upload方法返回false时submit()不生效解决方法
我要实现的功能是在上传文件之前校验是否表格中存在重复的数据,有的话,需要弹窗提示是否覆盖,确认之后继续上传,取消之后,就不再上传. 项目中用的element-ui是V1.4.3 <el-uplo ...
- 2017-11-06 日语编程语言"抚子" - 第三版特色初探
"中文编程"知乎专栏原链 原文: 日语编程语言"抚子" - 第三版特色初探 它山之石可以攻玉. 学习其他的母语编程语言, 相信对中文编程语言的设计和实践有借鉴意 ...