Java核心复习——J.U.C AbstractQueuedSynchronizer
背景和作用
在同步组件的实现中,AQS是核心部分,同步组件的实现者通过使用AQS提供的模板方法实现同步组件语义,AQS则实现了对同步状态的管理,以及对阻塞线程进行排队,等待通知等等一些底层的实现处理。AQS的核心也包括了这些方面:同步队列,独占式锁的获取和释放,共享锁的获取和释放以及可中断锁,超时等待锁获取这些特性的实现。
AQS
public abstract class AbstractOwnableSynchronizer
implements java.io.Serializable {
/**
* Empty constructor for use by subclasses.
*/
protected AbstractOwnableSynchronizer() { }
/**
* The current owner of exclusive mode synchronization.
*/
//独占模式下的线程
private transient Thread exclusiveOwnerThread;
// getter、setter
protected final void setExclusiveOwnerThread(Thread thread) {
exclusiveOwnerThread = thread;
}
protected final Thread getExclusiveOwnerThread() {
return exclusiveOwnerThread;
}
}
AQS#Node
/** Marker to indicate a node is waiting in shared mode */
static final Node SHARED = new Node();
/** Marker to indicate a node is waiting in exclusive mode */
static final Node EXCLUSIVE = null;
/** waitStatus value to indicate thread has cancelled */
static final int CANCELLED = 1;
/** waitStatus value to indicate successor's thread needs unparking */
static final int SIGNAL = -1;
/** waitStatus value to indicate thread is waiting on condition */
static final int CONDITION = -2;
/**
* waitStatus value to indicate the next acquireShared should
* unconditionally propagate
*/
static final int PROPAGATE = -3;
// 该变量主要记录线程的状态,确保线程是有效的,CANCELLED、SIGNAL、CONDITION、PROPAGATE
volatile int waitStatus;
volatile Node prev;
volatile Node next;
volatile Thread thread;
Node() { // Used to establish initial head or SHARED marker
}
Node(Thread thread, Node mode) { // Used by addWaiter
this.nextWaiter = mode;
this.thread = thread;
}
Node(Thread thread, int waitStatus) { // Used by Condition
this.waitStatus = waitStatus;
this.thread = thread;
}
AbstractQueuedSynchronizer
AQS使用CLH队列来实现线程排队的功能,CLH队列的原理是一个双向链表,每个链表由Node节点组成,Node节点保存prev和next两个指针,并保存指向线程的指针。
/**
* Head of the wait queue, lazily initialized. Except for
* initialization, it is modified only via method setHead. Note:
* If head exists, its waitStatus is guaranteed not to be
* CANCELLED.
*/
// 记录CLH的头部节点,目的是配合tail实现出队操作
private transient volatile Node head;
/**
* Tail of the wait queue, lazily initialized. Modified only via
* method enq to add new wait node.
*/
// 记录CLH的尾部节点
private transient volatile Node tail;
/**
* The synchronization state.
*/
// 用于记录加锁的次数,同一个线程加两次锁,则state = 2
private volatile int state;
/**
* Inserts node into queue, initializing if necessary. See picture above.
* @param node the node to insert
* @return node's predecessor
*/
// 入队操作
private Node enq(final Node node) {
for (;;) {
Node t = tail;
if (t == null) { // Must initialize
if (compareAndSetHead(new Node()))
tail = head;
} else {
node.prev = t;
if (compareAndSetTail(t, node)) {
t.next = node;
return t;
}
}
}
}
Java核心复习——J.U.C AbstractQueuedSynchronizer的更多相关文章
- Java核心复习 —— J.U.C 并发工具类
一.CountDownLatch 文档描述 A synchronization aid that allows one or more threads to wait until* a set of ...
- Java核心复习——J.U.C LinkedBlockingQueue源码分析
参考文档 LinkedBlockingQueue和ArrayBlockingQueue的异同
- Java核心复习——J.U.C ArrayBlockingQueue源码分析
介绍 依赖关系 源码 构造方法 public ArrayBlockingQueue(int capacity) { this(capacity, false);//默认构造非公平的有界队列 } pub ...
- Java核心复习——线程池ThreadPoolExecutor源码分析
一.线程池的介绍 线程池一种性能优化的重要手段.优化点在于创建线程和销毁线程会带来资源和时间上的消耗,而且线程池可以对线程进行管理,则可以减少这种损耗. 使用线程池的好处如下: 降低资源的消耗 提高响 ...
- Java:核心概念j积累(一)
1. 抽象 抽象就是忽略一个主题中与当前目标无关的那些方面,以便更充分地注意与当前目标有关的方面.抽象并不打算了解全部问题,而只是选择其中的一部分,暂时不用部分细节.抽象包括两个方面,一是过 ...
- Java核心复习—— 原子性、有序性与Happens-Before
一. 产生并发Bug的源头 可见性 缓存导致的可见性问题 原子性 线程切换带来的原子性问题 有序性 编译优化带来的有序性问题 上面讲到了 volatile 与可见性,本章再主要讲下原子性.有序性与Ha ...
- Java核心复习——synchronized
一.概念 利用锁机制实现线程同步,synchronized关键字的底层交由了JVM通过C++来实现 Java中的锁有两大特性: 互斥性 同一时间,只允许一个线程持有某个对象锁. 可见性 锁释放前,线程 ...
- Java核心复习—— volatile 与可见性
一.介绍 volatile保证共享变量的"可见性".可见性指的是当一个线程修改变量时,另一个线程能读到这个修改的值. 这里就要提出几个问题. 问题1:为什么一个线程修改时,另一个线 ...
- Java核心复习——CompletableFuture
介绍 JDK1.8引入CompletableFuture类. 使用方法 public class CompletableFutureTest { private static ExecutorServ ...
随机推荐
- 利用 pandas库读取excel表格数据
利用 pandas库读取excel表格数据 初入IT行业,愿与大家一起学习,共同进步,有问题请指出!! 还在为数据读取而头疼呢,请看下方简洁介绍: 数据来源为国家统计局网站下载: 具体方法 代码: i ...
- [转]理解Linux的性能
来源:http://www.linuxfly.org/post/114/ [转]理解Linux的性能 项目中常遇到需要对目前运行的系统进行效率分析,或碰到客户咨询如何优化系统的效率问题.更 ...
- Linux命令——lsb_release
简介 LSB是Linux Standard Base(Linux标准库)的缩写, lsb_release命令 用来与具体Linux发行版相关的Linux标准库信息. 注:LSB的译法有Linux标准库 ...
- Python_if语句
1.if语句: color='红色' if color=='蓝色': print('我是蓝色') elif color=='红色': print('我是红色') else : print('未知') ...
- LearnOpenGL学习笔记(一)画个三角形
开始学习OpenGL,参考的是著名的LearnOpenGL这个网站,在这里做一些总结性的记录,只是方便自己日后查找或者记录自己的一些拓展思考,关于OpenGL的具体内容请移步: https://lea ...
- Laravel 队列的简单使用例子
场景: 在一个a系统中注册一个用户时,发送请求到b系统中也注册一个相同信息的账号,考虑到网络有可能错误的原因,所以使用队列去处理 1.修改根目录 .env 文件的QUEUE_CONNECTION字段配 ...
- plus代码闪光点
1. 快速变成 String 格式: { stamp: +new Date() } 2. 封装axios请求: axios.get(this.URI, { params: { }, withCrede ...
- 云计算(3)-what is new in today's Cloud
What is new in today's Cloud Four features new in today's Clouds 如果一个problem有以上4个features里面的一个或者多个,则 ...
- Nginx 做JavaWeb负载均衡
随着用户量的增大,单台服务器已经满足不了用户的需求. 准备工作:安装 gcc.pcre-devel.zlib.OpenSSL 一下是在线 离线请戳这里 gcc 安装安装 nginx 需要先将官网下 ...
- 42 | grant之后要跟着flush privileges吗?
在 MySQL 里面,grant 语句是用来给用户赋权的.不知道你有没有见过一些操作文档里面提到,grant 之后要马上跟着执行一个 flush privileges 命令,才能使赋权语句生效.我最开 ...