并发编程J.U.C之AQS剖析
一、j.u.c简介
在说主题AQS之前,我们有必要先来说一下J.U.C
顾名思义J.U.C就是java.util.concurrent,java并发工具包。由我们的并发大师老爷子Doug Lea亲自操刀完成。而在这个包里,包含了我们大名鼎鼎的Lock、ConrurrentHashMap、CountDownLatch、Executor、LinkedBlockingQueue、ThreadPoolExecutor等重要的处理并发的类或者接口。当然,这些只是我听说过的一些。(此处应该有一个笑哭的表情),后续我将会带大家一一解读这些重要的并发工具。
废话不多说,让我们一步一步剥丝抽茧,解开AQS的神秘面纱。
二、AQS
1.AQS概要
AQS,全程AbstractQueuedSynchronizer--抽象队列同步器,他诞生于JDK1.5,是java中关于线程、同步的基础组件。如果对原文感兴趣的话,可以参见大师的原文:J.U.C Synchronizer Framework。既然作为基础组件,那么它便存在了大量的应用场景。
1.1 AQS应用场景
在此处,我们以可重入锁ReentrantLock来举例,说明AQS的内在原理。ReentrantLock关系类图如下:

package com.jarluo.AQS; import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock; /**
* @desc AQS应用场景之可冲入锁ReentrantLock
* @author jar luo
* @time 2019.5.21
*/
public class ReentrantLockDemo { static Lock lock = new ReentrantLock(); public static void main(String[] args) {
lock.lock();
try {
System.out.println("AQS应用场景之可冲入锁ReentrantLock");
} finally {
lock.unlock();
}
}
}
AQS应用场景
从上面的代码,我们可以看出,AQS应用起来还是很简单的,但是我们从关系类图中可以看到在ReentrantLock中维护了一个Sync内部类,同时Sync有两个子类,分别是NonFairSync和FairSync。此处我们主要对NonFairSync进行追踪(FairSync更加简单一些),可以得到以下时序图:
通过观察AQS源码发现,AQS 包含了以下几种核心技术点:
1.1 state
1.2 cas原子方法
1.3 自旋锁
1.4 CLH变种队列
沿着volitile状态管理-CAS原子操作-自旋锁-CLH队列进行展开
2.锁的基本要素
2.1 一个共享的数据来记录状态
二、Lock
0.synchronized和ReentrantLock的区别
1.关键字、一个是J.U.C
2.释放
局限性:不够灵活,锁释放要么执行完,要么出异常。
1.Lock是什么
1.1Lock是一个interface。
1.2Lock 提供了获得锁和释放锁的方法

2.重入锁
2.1 ReentrantLock 重入互斥锁--表示可以重新进入的锁。
2.1.1唯一实现了Lock接口的一个类。
lock.lock(),增加重入次数
synchronized也支持重入。
代码示例:
2.1.2 当多个线程竞争锁的时候,其他线程怎么办?
阻塞
2.2 ReentrantReadWriteLock --重入读写锁
读->读 是共享的
读->写 互斥
写->写 互斥
适用场景:读多写少的场景。
代码示例:
三、AQS--抽象队列同步器
1.概念:同步工具
2.功能:
2.1独占->互斥
2.2共享->读读
3.基本实现:
用双向链表去维护等待获得锁的线程对象
Node节点 上节点 下节点 线程
状态(state):锁标记
0是无锁状态
>=1是有锁状态(表示可以重入)
4.CAS
偏移量 cas(obj,offset,expect,update)
乐观锁
本地方法:
四、Sync
1.非公平锁--NonfairSync
允许插队
2.公平锁--FairSync
不允许插队
五、关系图
时序图
并发编程J.U.C之AQS剖析的更多相关文章
- 【死磕Java并发】-----J.U.C之AQS:CLH同步队列
此篇博客全部源代码均来自JDK 1.8 在上篇博客[死磕Java并发]-–J.U.C之AQS:AQS简单介绍中提到了AQS内部维护着一个FIFO队列,该队列就是CLH同步队列. CLH同步队列是一个F ...
- java并发编程笔记(六)——AQS
java并发编程笔记(六)--AQS 使用了Node实现FIFO(first in first out)队列,可以用于构建锁或者其他同步装置的基础框架 利用了一个int类型表示状态 使用方法是继承 子 ...
- java并发编程 | 锁详解:AQS,Lock,ReentrantLock,ReentrantReadWriteLock
原文:java并发编程 | 锁详解:AQS,Lock,ReentrantLock,ReentrantReadWriteLock 锁 锁是用来控制多个线程访问共享资源的方式,java中可以使用synch ...
- JAVA并发编程J.U.C学习总结
前言 学习了一段时间J.U.C,打算做个小结,个人感觉总结还是非常重要,要不然总感觉知识点零零散散的. 有错误也欢迎指正,大家共同进步: 另外,转载请注明链接,写篇文章不容易啊,http://www. ...
- 并发编程(十):AQS
AQS全称为AbstractQueuedSynchronizer,是并发容器中的同步器,AQS是J.U.C的核心,它是抽象的队列式的同步器,AQS定义了一套多线程访问共享资源的同步器框架,许多同步类都 ...
- 【死磕Java并发】—–J.U.C之AQS(一篇就够了)
[隐藏目录] 1 独占式 1.1 独占式同步状态获取 1.2 独占式获取响应中断 1.3 独占式超时获取 1.4 独占式同步状态释放 2 共享式 2.1 共享式同步状态获取 2.2 共享式同步状态释放 ...
- 【漫画】JAVA并发编程 J.U.C Lock包之ReentrantLock互斥锁
在如何解决原子性问题的最后,我们卖了个关子,互斥锁不仅仅只有synchronized关键字,还可以用什么来实现呢? J.U.C包中还提供了一个叫做Locks的包,我好歹英语过了四级,听名字我就能马上大 ...
- Java并发编程3-抽象同步队列AQS详解
AQS是AtractQueuedSynchronizer(队列同步器)的简写,是用来构建锁或其他同步组件的基础框架.主要通过一个int类型的state来表示同步状态,内部有一个FIFO的同步队列来实现 ...
- Java并发编程-深入Java同步器AQS原理与应用-线程锁必备知识点
并发编程中我们常会看到AQS这个词,很多朋友都不知道是什么东东,博主经过翻阅一些资料终于了解了,直接进入主题. 简单介绍 AQS是AbstractQueuedSynchronizer类的缩写,这个不用 ...
随机推荐
- CentOS7安装后无法使用鼠标选中
运行命令:yum install gpm* 安装gpm 启动gpm服务:service gpm start 运行systemctl enable gpm.servicere 添加到后台服务. 备注: ...
- 如何写resultful接口
一.协议 API与客户端用户的通信协议,总是使用HTTPS协议,以确保交互数据的传输安全. 二.域名 应该尽量将API部署在专用域名之下: https://api.example.com 如果确定AP ...
- 纹理特征描述之灰度差分统计特征(平均值 对比度 熵) 计算和比较两幅纹理图像的灰度差分统计特征 matlab代码实现
灰度差分统计特征有: 平均值: 对比度: 熵: i表示某一灰度值,p(i)表示图像取这一灰度值的概率 close all;clear all;clc; % 纹理图像的灰度差分统计特征 J = i ...
- 日常小节----unity小坑记(静态后不可移动和旋转)
当物体被置为静态时,模型网格是无法移动和旋转的,只有碰撞器可以. 也就是会出现当父物体不为静态,子物体为静态时,运行后旋转移动父物体,子物体模型网格不会跟随旋转移动,但子物体碰撞器会跟随旋转移动. 或 ...
- STL————vector的用法
一.什么是vector? 向量(Vector)是一个封装了动态大小数组的顺序容器(Sequence Container).跟任意其它类型容器一样,它能够存放各种类型的对象.可以简单的认为,向量是一个能 ...
- kubernetes 简单 hello world nginx svc deployment
1.nginx svc deployment [root@k8s k8s4nginx]# cat deploynginx.yaml ################################# ...
- linux学习命令收集
多看看大神的博客 https://blog.csdn.net/tao934798774/article/details/79491951 ip addr 查看ip地址 ifconfig 查看i ...
- English 邮件
1.email http://www2.elc.polyu.edu.hk/cill/eiw/e-mail.htm
- Base64encoder干什么用的
https://baike.baidu.com/item/base64/8545775?fr=aladdin BASE64加密算法.用来给字符串加密的.已经不安全了. 一直以来Base64的加密解密都 ...
- 使用winsw包装服务将nginx包装为Windows服务
**Nginx本身在Windows上并不支持以服务的形式运行,官方文件中有提到.http://nginx.org/en/docs/windows.html,所以在Windows下使用winsw将Ngi ...