前言 最近结合书籍<Java并发编程艺术>一直在看AQS的源码,发现AQS核心就是:利用内置的FIFO双向队列结构来实现线程排队获取int变量的同步状态,以此奠定了很多并发包中大部分实现基础,比如ReentranLock等.今天又是周末,便来总结下最近看的消化后的内容. 主要参考资料<Java并发编程艺术>(有需要的小伙伴可以找我,我这里只有电子PDF)结合ReentranLock.AQS等源码. 博文中的流程图,结构图等都是我理解之后一步步亲自画的,如果转载,请标明谢谢! 一.同…
前言 在Java多线程中的wait/notify通信模式结尾就已经介绍过,Java线程之间有两种种等待/通知模式,在那篇博文中是利用Object监视器的方法(wait(),notify().notifyAll())实现的,然而在实际生产环境中不推荐使用此方法,建议使用condition的等待通知模式,JUC包中很多核心实现也确实证实了这点,所以这必然是学习JUC包源码的基础. 如果之前阅读过前不久介绍同步队列的博文学习JUC源码(1)--AQS同步队列(源码分析结合图文理解),就能更好理解Con…
前言 由于AQS的源码太过凝练,而且有很多分支比如取消排队.等待条件等,如果把所有的分支在一篇文章的写完可能会看懵,所以这篇文章主要是从正常流程先走一遍,重点不在取消排队等分支,之后会专门写一篇取消排队和等待条件的分支逻辑.读源码千万别在每个代码分支中来回游走,先按一个正常的分支把流程看明白,之后再去重点关注其他分支,各个击破.我相信看完正常流程,你再去分析其他分支会更加得心应手.本篇将主要方法名都做了目录索引,查看时可通过目录快速跳到指定方法的逻辑. 执行流程 AQS的执行流程大体为当线程获取…
前言 在之前的博文(学习JUC源码(1)--AQS同步队列(源码分析结合图文理解))中,已经介绍了AQS同步队列的相关原理与概念,这里为了再加深理解ReentranLock等源码,模仿构造同步组件的基本模式,编写不可重复的互斥锁Mutex与指定共享线程数量的共享锁.MySharedLock. 主要参考资料<Java并发编程艺术>(有需要的小伙伴可以找我,我这里只有电子PDF)同时结合ReentranLock.AQS等源码. 一.构造同步组件的模式 丛概念方层面,在中,我们知道锁与同步器的相关概…
目录 Condition接口 AQS条件变量的支持之ConditionObject内部类 回顾AQS中的Node void await() 添加到条件队列 Node addConditionWaiter() void unlinkCancelledWaiters() 完全释放独占锁 int fullyRelease(Node node) 等待进入阻塞队列 boolean isOnSyncQueue(Node node) boolean findNodeFromTail(Node node) vo…
入队 Node AQS同步队列和等待队列共用同一种节点结构Node,与同步队列相关的属性如下. prev 前驱结点 next 后继节点 thread 入队的线程 入队节点的状态 INITIAl 0 初始状态.当一个节点刚刚被加入同步队列时的默认值 SIGNAL -1 状态为-1的Node意味着该节点有一个后继节点在等待,也就是说如果Status=-1的节点释放锁后需要他的后继节点(next).一个节点的waitStatuc被设置成-1只能有其后继节点设置,自己不能设置. CONDITION -2…
概要: AQS维护了一个同步队列 Condition是JUC的一个接口,AQS的ConditionObject实现了这个接口,维护了一个等待队列(等待signal信号的队列) 线程调用reentrantLock.lock()时,线程被加入到AQS同步队列中: 线程A调用condition.await()方法时,线程A从AQS同步队列中被移除,被加入到Condition等待队列,等待signal信号 线程B调用signal()方法,Condition等待队列中有一个节点A,把它取出来(A)加入到A…
目录 本篇学习目标 CLH队列的结构 资源获取 入队Node addWaiter(Node mode) 不断尝试Node enq(final Node node) boolean acquireQueued(Node, int) 出队void setHead(Node) boolean shouldParkAfterFailedAcquire(Node,Node) boolean parkAndCheckInterrupt() void cancelAcquire(node) 释放资源 bool…
要深入了解java并发知识,AbstractQueuedSynchronizer(AQS)是必须要拿出来深入学习的,AQS可以说是贯穿了整个JUC并发包,例如ReentrantLock,CountDownLatch,CyclicBarrier等并发类都涉及到了AQS.接下来就对AQS的实现原理进行分析. 在开始分析之前,势必先将CLH同步队列了解一下 CLH同步队列 CLH自旋锁: CLH(Craig, Landin, and Hagersten locks): 是一个自旋锁,能确保无饥饿性,提…
目录 1 疑点todo和解疑 2 AbstractQueuedSynchronizer学习总结 2.1 AQS要点总结 2.2 细节分析 2.2.1 插入节点时先更新prev再更新前驱next 2.2.2 为什么unparkSuccessor()要从尾部往前遍历 2.2.3 AQS的设计,尽快唤醒其他等待线程体现在3个地方 3 AQS 简介 3.1 AQS核心思想 3.2 对资源的共享方式 3.3 AQS数据结构 4 AbstractQueuedSynchronizer源码分析 4.1 类的继承…
[Java并发] AQS抽象队列同步器源码解析--独占锁获取过程 上一篇已经讲解了AQS独占锁的获取过程,接下来就是对AQS独占锁的释放过程进行详细的分析说明,废话不多说,直接进入正文... 锁释放入口release(int arg) 首先进行说明下,能够正常执行到release方法这里来的线程都是获取到锁的,从下面代码可以看出释放锁步骤只有两个重要的方法:tryRelease 与unparkSuccessor ,tryRelease尝试释放锁,unparkSuccessor唤醒后继节点所封装的…
前言: 如果说J.U.C包下的核心是什么?那我想答案只有一个就是AQS.那么AQS是什么呢?接下来让我们一起揭开AQS的神秘面纱 AQS是什么? AQS是AbstractQueuedSynchronizer的简称.为什么说它是核心呢?是因为它提供了一个基于FIFO的队列和state变量来构建锁和其他同步装置的基础框架.下面是其底层的数据结构. AQS的特点 1.其内使用Node实现FIFO(FirstInFirstOut)队列.可用于构建锁或者其他同步装置的基础框架 2.且利用了一个int类表示…
一.ReentrantLock与AQS简介 在Java5.0之前,在协调对共享对象的访问时可以使用的机制只有synchronized和volatile.Java5.0增加了一种新的机制:ReentrantLock.ReentrantLock并不是一种替代内置加锁的方法,而是作为一种可选择的高级功能.ReentrantLock实现了Lock接口,提供了一种无条件的.可轮询的.定时的以及可中断的锁获取操作,所有加锁和解锁方法都是显式的. 我们基本不会直接使用AQS,AQS是一个构建锁和同步器的框架,…
AQS是AtractQueuedSynchronizer(队列同步器)的简写,是用来构建锁或其他同步组件的基础框架.主要通过一个int类型的state来表示同步状态,内部有一个FIFO的同步队列来实现. AQS的使用方式是通过子类继承来实现,子类继承同步器并且实现抽象方法来完成同步,实现过程中涉及到同步状态的方法主要有: getState():获取同步状态 setState(int newState):设置同步状态 compareAndSetState(int expect,int update…
一.前言 AQS 是一个同步框架,关于同步在操作系统(一)-- 进程同步 中对进程同步做了些概念性的介绍,我们了解到进程(线程同理,本文基于 JVM 讲解,故下文只称线程)同步的工具有很多:Mutex.Semaphore.Monitor.但是Mutex 和 Semaphore 作为低级通信存在不少缺点,Monitor 机制解决了上面部分缺憾,但是仍然存在问题,AQS 的出现很好的解决了这些问题. 二.其他同步工具的缺点 Mutex Mutex 只有两种状态,锁定和非锁定,无法表示临界区的可用资源…
在[Java并发编程实战]-–"J.U.C":CLH队列锁提过,AQS里面的CLH队列是CLH同步锁的一种变形.其主要从两方面进行了改造:节点的结构与节点等待机制.在结构上引入了头结点和尾节点,他们分别指向队列的头和尾,尝试获取锁.入队列.释放锁等实现都与头尾节点相关,并且每个节点都引入前驱节点和后后续节点的引用:在等待机制上由原来的自旋改成阻塞唤醒.其结构如下: 知道其结构了,我们再看看他的实现.在线程获取锁时会调用AQS的acquire()方法,该方法第一次尝试获取锁如果失败,会将…
文章转载自 AbstractQueuedSynchronizer的介绍和原理分析 建议去看一下原文的评论,会有不少收获. 简介 AbstractQueuedSynchronizer 提供了一个基于FIFO队列,可以用于构建锁或者其他相关同步装置的基础框架.该同步器(以下简称同步器)利用了一个int来表示状态,期望它能够成为实现大部分同步需求的基础.使用的方法是继承,子类通过继承同步器并需要实现它的方法来管理其状态,管理的方式就是通过类似acquire和release的方式来操纵状态.然而多线程环…
上一篇 细说并发4:Java 阻塞队列源码分析(上) 我们了解了 ArrayBlockingQueue, LinkedBlockingQueue 和 PriorityBlockingQueue,这篇文章来了解剩下的四种阻塞队列. 读完本文你将了解: 七种阻塞队列的后四种 DelayQueue DelayQueue 的关键属性 实现 Delayed 接口 延时阻塞队列如何实现 DelayQueue 使用场景 SynchronousQueue LinkedTransferQueue Transfer…
此篇博客所有源码均来自JDK 1.8 在上篇博客[死磕Java并发]—–J.U.C之AQS:AQS简介中提到了AQS内部维护着一个FIFO队列,该队列就是CLH同步队列. CLH同步队列是一个FIFO双向队列,AQS依赖它来完成同步状态的管理,当前线程如果获取同步状态失败时,AQS则会将当前线程已经等待状态等信息构造成一个节点(Node)并将其加入到CLH同步队列,同时会阻塞当前线程,当同步状态释放时,会把首节点唤醒(公平锁),使其再次尝试获取同步状态. 在CLH同步队列中,一个节点表示一个线程…
Spring 源码学习过程: 一.搞明白IOC能做什么,是怎么做的  1. 搞明白IOC能做什么? IOC是用为用户创建.管理实例对象的.用户需要实例对象时只需要向IOC容器获取就行了,不用自己去创建,从而达到与具体类解耦.  2. IOC是怎么做到的,即它的实现步骤是怎么样的? 2.1 用户配置bean定义 我们使用Spring IOC时有几种方式来配置bean定义呢? xml的方式: <bean id="abean" class="com.study.spring.…
Springboot学习04-默认错误页面加载机制源码分析 前沿 希望通过本文的学习,对错误页面的加载机制有这更神的理解 正文 1-Springboot错误页面展示 2-Springboot默认错误处理逻辑 1-将请求转发到BasicErrorController控制器来处理请求, 2-浏览器请求响应BasicErrorController的errorHtml()方法,APP等客户端响应error()方法 3-以浏览器的404错为例:最终返回一个modelAndView 3-1-调用BasicE…
此篇博客全部源代码均来自JDK 1.8 在上篇博客[死磕Java并发]-–J.U.C之AQS:AQS简单介绍中提到了AQS内部维护着一个FIFO队列,该队列就是CLH同步队列. CLH同步队列是一个FIFO双向队列,AQS依赖它来完毕同步状态的管理,当前线程假设获取同步状态失败时,AQS则会将当前线程已经等待状态等信息构造成一个节点(Node)并将其加入到CLH同步队列,同一时候会堵塞当前线程,当同步状态释放时,会把首节点唤醒(公平锁),使其再次尝试获取同步状态. 在CLH同步队列中,一个节点表…
正如上篇文章聊聊 JDK 阻塞队列源码(ReentrantLock实现)所说,队列在我们现实生活中队列随处可见,最经典的就是去银行办理业务,超市买东西排队等.今天楼主要讲的就是JDK中安全队列的另一种实现使用CAS算法实现的安全队列. JDK 中的队列 在JDK中的队列都实现了 java.util.Queue 接口,下面就是楼主要说的无锁版本的队列实现: 队列名字 是否加锁 数据结构 LinkedTransferQueue 否 链表 ConcurrentLinkedQueue 否 链表 Link…
在[Java并发编程实战]-–"J.U.C":CLH队列锁提过,AQS里面的CLH队列是CLH同步锁的一种变形. 其主要从双方面进行了改造:节点的结构与节点等待机制.在结构上引入了头结点和尾节点,他们分别指向队列的头和尾,尝试获取锁.入队列.释放锁等实现都与头尾节点相关.而且每一个节点都引入前驱节点和后兴许节点的引用:在等待机制上由原来的自旋改成堵塞唤醒. 其结构例如以下: 知道其结构了,我们再看看他的实现.在线程获取锁时会调用AQS的acquire()方法.该方法第一次尝试获取锁假设…
JDK数组阻塞队列源码深入剖析 前言 在前面一篇文章从零开始自己动手写阻塞队列当中我们仔细介绍了阻塞队列提供给我们的功能,以及他的实现原理,并且基于谈到的内容我们自己实现了一个低配版的数组阻塞队列.在这篇文章当中我们将仔细介绍JDK具体是如何实现数组阻塞队列的. 阻塞队列的功能 而在本篇文章所谈到的阻塞队列当中,是在并发的情况下使用的,上面所谈到的是队列是并发不安全的,但是阻塞队列在并发下情况是安全的.阻塞队列的主要的需求如下: 队列基础的功能需要有,往队列当中放数据,从队列当中取数据. 所有的…
Netty 学习(八):新连接接入源码说明 作者: Grey 原文地址: 博客园:Netty 学习(八):新连接接入源码说明 CSDN:Netty 学习(八):新连接接入源码说明 新连接的接入分为3个过程 检测到有新连接. 将新连接注册到 worker 线程. 注册新连接的读事件. 检测新连接的代码在NioEventLoop中的processSelectedKey()方法中 private void processSelectedKey(SelectionKey k, AbstractNioCh…
前言: 今天github push代码一直push不上去,打算就备份一份代码带国内开源码云上. Github容易出现的情况是: 国内访问速度比较慢, 如果被墙掉的话,就直接没发使用了 如果开源个PHP的项目,想把扩展文件目录vender一并上传上去,这样子下载的时候使用github会很慢 从今天开始,我将会使我的开源项目同时推送到github和码云. 实战 前提:你的代码已经在Github仓库和码云仓库了 1.项目案例: Github:https://github.com/Tinywan/htm…
(一)什么是AQS? 阅读java文档可以知道,AbstractQueuedSynchronizer是实现依赖于先进先出 (FIFO) 等待队列的阻塞锁和相关同步器(信号量.事件,等等)提供一个框架,它是一个依靠单个原子 int 值来表示状态的大多数同步器的一个基础类.在jdk中他的实现的类有Semaphore,ReentrantLock,CountDownLatch,ReentrantReadWriteLock等等很多的实现. (二)原理 它通过实现一个volatile int state来维…
一行一行源码分析清楚AbstractQueuedSynchronizer 转自https://www.javadoop.com/post/AbstractQueuedSynchronizer#toc4 在分析 Java 并发包 java.util.concurrent 源码的时候,少不了需要了解 AbstractQueuedSynchronizer(以下简写AQS)这个抽象类,因为它是 Java 并发包的基础工具类,是实现 ReentrantLock.CountDownLatch.Semapho…
一.论文简介 闲来无事,看看源码,发现了一篇JDK作者的论文<The java.util.concurrent Synchronizer Framework>主要描述了作者对AbstractQueuedSynchronizer同步器框架的设计和实现.权威性毋庸置疑!自然需要拜读一下,配上中文翻译,希望大家能有所收获. 二.原文链接 论文英文版原文链接:http://gee.cs.oswego.edu/dl/papers/aqs.pdf 打开链接右上角有下载按钮 http://gee.cs.os…