![](https://img-blog.csdnimg.cn/4cac5c1ec54c4ae589cda78e2f2f5cd5.jpeg?x-oss-process=image/resize,m_fixed,h_224,w_224)
【JAVA】JUC 之 AQS 与 锁实现篇
文章平均质量分 71
本专栏详细讲解了 JUC 中 AQS 的实现 与 基于 AQS 实现的同步器源码
wpml_java
从事java研发工作多年
展开
-
JUC 之 CyclicBarrier 源码分析
通过上述源码可以看到,只有所有线程都到达屏障点后才属于正常情况,这时会调用 nextGeneration 方法唤醒所有等待线程、复位 count、生成新的 generation。而其他线程可能会因为被中断或超时都会造成本轮次操作的失败,即 generation.broken 被设置为了 true,其它线程检测到该值被设置纷纷抛出 BrokenBarrierException 异常而退出等待原创 2023-07-20 13:52:21 · 37 阅读 · 0 评论 -
JUC 之 CountDownLatch 源码分析
以上就是 CountDownLatch 的实现原理。就是利用 AQS 共享锁机制的同步器 Sync 来实现的。 此处读者需要注意的是 CountDownLatch 一旦创建只可使用一次,不能重复使用原创 2023-07-19 15:46:21 · 28 阅读 · 0 评论 -
JUC 之 Semaphore 信号量
利用 AQS 的共享锁机制,初始设置一个固定 state 值(初始容量),当有线程需要获取访问权时,检测 state 是否有可用资源,state > 0 代表有资源可用,获取到访问凭证后将 state 减 1;只要 state > 0 其他线程就可以获取访问凭证,直到 state = 0。利用该特性就可以完成对接口的限流操作,控制并发请求量。原创 2023-07-18 16:29:34 · 46 阅读 · 0 评论 -
JUC 之 ReentrantReadWriteLock 读写锁
通过上述源码的学习,我们知道了读写锁的实现流程。AQS 提供 state 单变量和 队列的功能,ReentrantReadWriteLock 通过操作这两个信息完成自己的功能。通过将一个整型变量 state 切割为 高低 16 位,分别用于保存读锁和写锁的信息,高 16 位表示读锁,低 16 位表示写锁。原创 2023-07-17 11:22:38 · 96 阅读 · 0 评论 -
JUC 之 ReentrantLock 源码解析
前面我们学习了 AQS 的源码,了解了 AQS 的实现原理,为我们后面即将学习的 ReentrantLock、ReentrantReadWriteLock、CountDownLatch、Semaphore 等奠定了扎实的基础。Java 中同步器的实现均离不开 AQS 的支持。那么下面我们就从 ReentrantLock 开始逐一进行讲解。原创 2023-07-15 19:38:30 · 37 阅读 · 0 评论 -
AQS 之 Condition 源码剖析
前面我们详细讲解了互斥锁与共享锁的源码实现。有一种情况,我们可不可以控制程序在满足某一条件在继续执行呢?答案是 能,怎么做呢?JDK 提供了 Condition 条件接口,我们通过实现该接口就能控制程序的执行,下面我们来看看 AQS 中 ConditionObject 的具体实现。在看它的时候,我们只需要记住一点,针对 ConditionObject 的所有操作都是线程安全的,因为只有在先获取到锁才能去操作 ConditionObject。原创 2023-07-14 09:51:57 · 54 阅读 · 0 评论 -
AQS 之 共享锁 源码剖析
上一篇我们详细讲解了互斥锁的源码实现,也即同一时刻只有一个线程获得锁,其它参与竞争的线程必须等待。有一种情况是允许多个线程同时获得锁,如读写锁(ReentrantReadWriteLock)允许所有读线程同时获取锁,写线程阻塞,也即读读共享,读写互斥,写写互斥。那么接下来我们就来看看共享锁的源码实现。原创 2023-07-14 08:49:24 · 236 阅读 · 0 评论 -
AQS 之 互斥锁 源码剖析
AQS 是 AbstractQueuedSynchronizer 类的简称,AQS 是一个用来构建锁和同步器的基础框架,想要了解 Java 的锁实现及其底层原理就必须先了解 AQS 完成了什么,提供了哪些功能。有了AQS的基础支撑我们后面再去学 Java 锁(如ReentrantLock、ReentrantReadWriteLock、Semaphore等)相关类的源码时就会觉得很轻松。那么下面我们就开始进入 AQS 的源码之旅。原创 2023-07-09 11:23:55 · 69 阅读 · 0 评论 -
JUC源码系列之ThreadPoolExecutor
** 通过位组合的方式将线程池的运行状态和工作线程数保存在一个变量 ctl 中,高三位表示运行状态,低 29 位保存工作线程数 */ private final AtomicInteger ctl = new AtomicInteger(ctlOf(RUNNING , 0));/** COUNT_BITS 29位 */ private static final int COUNT_BITS = Integer . SIZE - 3;原创 2023-03-30 15:26:15 · 54 阅读 · 0 评论 -
JUC源码系列之LinkedBlockingQueue
基于单向链表实现的有界阻塞队列,遵循先进先出(FIFO)原则。可用于实现一个生产者消费者模型,由于内部使用了 takeLock 和 putLock 两把锁,还有notEmpty 和 notFull 两个条件变量,因此它可以做到读与写并行操作。使用 AtomicInteger 记录队列中元素的个数。/** 队列的容量,默认为 int 的最大值 */ private final int capacity;原创 2023-03-28 15:59:46 · 45 阅读 · 0 评论 -
JUC源码系列之SynchronousQueue
** 表示当前节点是消费者线程 */ static final int REQUEST = 0;/** 表示当前节点是生产者线程 */ static final int DATA = 1;/** 表示当前节点是匹配节点线程 */ static final int FULFILLING = 2;/** 栈的头节点 */ volatile SNode head;SNode节点变量介绍// 指向下一个节点的指针 volatile SNode match;原创 2023-03-22 17:28:09 · 111 阅读 · 0 评论 -
JUC-LongAdder
对于AtomicLong原子类虽然能保证线程操作的原子性,但是在多线程竞争的情况下同时只会有一个线程能获取到锁进行累加操作,其他CPU只能在那自旋空转(浪费CPU资源)。而对于LongAdder来说,当存在多线程并发操作时,会将其累加操作分散到不同的cell中,增加的了线程并行度(最大限度的压榨CPU,减少CPU空转),进而提升了性能。累加操作,核心就是当存在多线程竞争的时候,将CAS操作分散到不同的cell 中,最后获取总值的时候将各个cell中的值与base的值累加返回。1、cells数组没有初始化。原创 2023-03-09 19:57:09 · 39 阅读 · 0 评论 -
ThreadLocal内存泄漏源码分析
TLM中存放的是一系列的Entry对象,entry中 key 是弱引用的TL,value是我们需要保存的值(强引用),通过上图的是示例代码发现,当TL被回收后发现value的值还存在,此时如果该线程一直处于执行中,那么value的值就属于内存泄漏(该value值永远存在无法被GC)。通过当前TL算出其对应的索引下标 i 的值,从当前下标向后遍历知道数组项为空停止,找到当前项清除即可,调用expungeStaleEntry方法清除其他失效的数组项。每个线程都有独立的TL,线程私有变量,多线程安全。原创 2023-03-09 19:52:41 · 122 阅读 · 0 评论