备注:博文仅仅是学习过程中的零散记录,后期整理。

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的入门(一)的更多相关文章

  1. Java中关于AbstractQueuedSynchronizer的入门(二)

    AQS是一个同步器的基础类,里面的关键字段: //如下关键字段都是volatile类型 /** * Head of the wait queue, lazily initialized. Except ...

  2. Java中的IO流 - 入门篇

    前言 大家好啊,我是汤圆,今天给大家带来的是<Java中的IO流-入门篇>,希望对大家有帮助,谢谢 由于Java的IO类有很多,这就导致我刚开始学的时候,感觉很乱,每次用到都是上网搜,结果 ...

  3. Java中的集合List - 入门篇

    前言 大家好啊,我是汤圆,今天给大家带来的是<Java中的集合List - 入门篇>,希望对大家有帮助,谢谢 简介 说实话,Java中的集合有很多种,但是这里作为入门级别,先简单介绍第一种 ...

  4. Java中的映射Map - 入门篇

    前言 大家好啊,我是汤圆,今天给大家带来的是<Java中的映射Map - 入门篇>,希望对大家有帮助,谢谢 简介 前面介绍了集合List,这里开始简单介绍下映射Map,相关类如下图所示 正 ...

  5. Java中的集合Set - 入门篇

    前言 大家好啊,我是汤圆,今天给大家带来的是<Java中的集合Set - 入门篇>,希望对大家有帮助,谢谢 简介 前面介绍了集合List,映射Map,最后再简单介绍下集合Set,相关类如下 ...

  6. Java中Redis的简单入门

    1.下载redis服务器端程序: 在redis.io官网完成服务器端程序下载:可下载安装版或解压版,此处我下载的是解压版,下载完成后解压. 2.配置redis密码,开启redis服务端 在redis. ...

  7. Java中Redis简单入门

    Redis是一个开源的,先进的 key-value 存储可用于构建高性能,可扩展的 Web 应用程序的解决方案. Redis官方网网站是:http://www.redis.io/,如下: Redis ...

  8. 【JAVA零基础入门系列】Day5 Java中的运算符

    运算符,顾名思义就是用于运算的符号,比如最简单的+-*/,这些运算符可以用来进行数学运算,举个最简单的栗子: 已知长方形的长为3cm,高为4cm,求长方形的面积. 好,我们先新建一个项目,命名为Rec ...

  9. 【JAVA零基础入门系列】Day9 Java中的那个大数值

    什么是大数值?用脚趾头想也知道,当然是"大"的数值(233).Java中有两个用于表示大数值的类,BigInteger和BigDecimal,那到底能表示多大的数值呢?理论上,可以 ...

随机推荐

  1. ActiveReport系列报表开发随笔收集

    转自:博客园 http://www.cnblogs.com/dahuzizyd/archive/2007/04/11/ActiveReport_All.html 使用ActiveReport for ...

  2. LeetCode子域名访问计数-Python3.7<五>

    上一篇:LeetCode 键盘行<四> 题目:https://leetcode-cn.com/problems/subdomain-visit-count/description/ 一个网 ...

  3. [android] 手机卫士自定义滚动控件

    TextView控件设置单行显示 android:singleLine=”true” 设置TextView开始的位置显示省略号,android:ellipsize=”start” 设置滚动属性,and ...

  4. httpclient请求服务的各种方法实例

    <!--话不多说,直接上代码--> import com.csis.ConfigManagerimport com.csis.io.web.DefaultConfigItemimport ...

  5. @RequestBody发送请求报400错误

    参数不使用@RequestBody 在使用Postman进行Post请求时,通常做法是填入key和value的值即可. 参数使用@RequestBody 使用@RequestBody注解时,在发送请求 ...

  6. AOP,过滤器,监听器,拦截器【转载】

    面向切面编程(AOP是Aspect Oriented Program的首字母缩写) ,我们知道,面向对象的特点是继承.多态和封装.而封装就要求将功能分散到不同的对象中去,这在软件设计中往往称为职责分配 ...

  7. APP(通信)接口定义

  8. 【CF932E】Team Work(第二类斯特林数)

    [CF932E]Team Work(第二类斯特林数) 题面 洛谷 CF 求\(\sum_{i=1}^nC_{n}^i*i^k\) 题解 寒假的时候被带飞,这题被带着写了一遍.事实上并不难,我们来颓柿子 ...

  9. 【读书笔记】iOS-解析JSON

    JSON相比XML最显著的优点是不需要使用重量级的解析库,因为其本身就是面向数据的,而且非常容易转换成哈希字典.除此之外,JSON文档相比同样的XML文档更小.在网络宽带有限的情况下,你很容易在Iph ...

  10. 学习css(TODO)

    1. css 是一个什么样的角色? 答:css 负责控制网页的样式. 扩展:div + css 是经典的网页布局.实现网页内容与表现相分离. 2. css 的使用方式? 答:1. 内联式:直接在 HT ...