JDK
文章平均质量分 96
JDK源码阅读笔记
Sumkor
会写点代码
展开
-
阅读 JDK 源码:线程池 ThreadPoolExecutor
上一篇文章介绍了 Thread 类,可知线程随着任务的执行结束而被销毁。但是,由于线程的创建与销毁操作涉及到系统调用,开销较大,因此需要将线程的生命周期与任务进行解耦。使用线程池来管理线程,可以有效地重复利用线程来执行任务。本文将介绍线程池最基础的实现类 ThreadPoolExecutor。本文基于 jdk1.8.0_91文章目录1. 线程池体系2. 构造方法2.1 源码分析2.2 使用说明2.2.1 Core and maximum pool sizes2.2.2 On-demand const原创 2021-05-16 19:28:26 · 466 阅读 · 0 评论 -
阅读 JDK 源码:线程类 Thread
在 Java 中,使用 Thread 类可以在操作系统层面创建线程,并绑定到对应的 Thread 类实例中。利用线程异步地执行任务,是并发编程的基础。本文通过阅读 Thread 源码,了解线程状态的定义,线程调度的相关方法,以及对线程中断的处理等。本文基于 jdk1.8.0_91原创 2021-05-13 00:43:59 · 170 阅读 · 0 评论 -
阅读 JDK 源码:异步任务 FutureTask
在 Java 中,Runnable 接口表示一个没有返回结果的任务,而 Callable 接口表示具有返回结果的任务。在并发编程中,异步执行任务,再获取任务结果,可以提高系统的吞吐量。Future 接口应运而生,它表示异步任务的执行结果,并提供了检查任务是否执行完、取消任务、获取任务执行结果等功能。FutureTask 是 Future 接口的基本实现,常与线程池实现类 ThreadPoolExecutor 配合使用。本文基于 jdk1.8.0_91文章目录1. 继承体系2. 属性2.原创 2021-05-03 15:33:01 · 473 阅读 · 0 评论 -
阅读 JDK 源码:读写锁 ReentrantReadWriteLock
在 JUC 包中,共享锁包括 CountDownLatch、CyclicBarrier、Semaphore 等。ReentrantReadWriteLock 是基于 AQS(AbstractQueuedSynchronizer)框架实现的锁工具,其中定义了两个锁:共享锁 readLock 和独占锁 writeLock。readLock 用于读操作,能同时被多个线程获取;writeLock 用于写入操作,只能被一个线程持有。读锁、写锁均具有公平模式、非公平模式两种获取锁的方式。原创 2021-05-01 13:31:54 · 903 阅读 · 0 评论 -
阅读 JDK 源码:可重入锁 ReentrantLock
前几篇文章介绍了 AQS(AbstractQueuedSynchronizer)中的独占模式和对 Condition 的实现,这一篇文章来聊聊基于 AQS 框架实现的锁工具:ReentrantLock。ReentrantLock 是一个可重入的互斥锁,也被称为独占锁。具有两种实现:公平锁(fair lock)、非公平锁(non-fair lock)。本文基于 jdk1.8.0_91原创 2021-04-28 23:50:04 · 150 阅读 · 0 评论 -
阅读 JDK 源码:AQS 对 Condition 的实现
前两篇文章分别介绍了 AQS 框架中的独占模式和共享模式,本篇将介绍 AQS 对 Condition 接口的实现。在阅读本篇之前,建议先了解 AQS 中的数据结构和独占模式的实现原理。JUC 通过 Lock 和 Condition 两个接口实现管程(Monitor),其中 Lock 用于解决互斥问题,而 Condition 用于解决同步问题,而 AQS 对 Lock 和 Condition 接口的实现提供了一个基础的框架。文章目录1. Condition 接口2. Condition 使用3. Con原创 2021-04-25 20:55:02 · 286 阅读 · 0 评论 -
阅读 JDK 源码:AQS 中的共享模式
AbstractQueuedSynchronizer,简称 AQS,是一个用于构建锁和同步器的框架。上一篇文章介绍了 AQS 的数据结构和独占模式的实现原理,本篇介绍 AQS 共享模式的源码实现。文章目录1. 共享模式1.1 获取锁-acquireShared1.1.1 tryAcquireShared1.1.2 doAcquireSharedsetHeadAndPropagatedoReleaseShared1.2 释放锁-releaseShared原创 2021-04-25 17:11:36 · 267 阅读 · 0 评论 -
阅读 JDK 源码:AQS 中的独占模式
AbstractQueuedSynchronizer,简称 AQS,是一个用于构建锁和同步器的框架。JUC 包下常见的锁工具如 ReentrantLock、ReentrantReadWriteLock、Semaphore、CountDownLatch 都是基于 AQS 实现的。文章目录1. AQS 框架1.1 继承体系1.2 模板方法2. 数据结构2.1 资源定义2.2 节点定义2.3 同步队列2.4 条件队列3. 独占模式3.1 获取锁-acquire3.1.1 tryAcquire3.1.2 add原创 2021-04-25 17:03:31 · 124 阅读 · 0 评论 -
阅读 JDK 源码:传递队列 LinkedTransferQueue
LinkedTransferQueue 是一个由链表结构组成的无界阻塞 TransferQueue 队列。接口 TransferQueue 和实现类 LinkedTransferQueue 从 Java 7 开始加入 J.U.C 之中。文章目录1. 继承体系2. 数据结构2.1 节点定义2.2 head 和 tail 节点3. 构造函数4. 数据存取及传递4.1 xfer4.2 匹配过程图示4.3 tryAppend4.4 awaitMatch4.5 自旋次数4.6 unsplice5. 容量6. 总结原创 2021-04-19 21:38:40 · 248 阅读 · 0 评论 -
阅读 JDK 源码:松弛队列 ConcurrentLinkedQueue
ConcurrentLinkedQueue 是一个由链表结构组成的无界非阻塞队列,是 JDK 中唯一一个并发安全的非阻塞队列。使用无锁算法来保证线程安全,为了减少 CAS 操作造成的资源争夺损耗,其链表结构被设计为“松弛”的,本文对 ConcurrentLinkedQueue 的入队和出队过程进行图解,直观展示其内部结构。文章目录1. 继承体系2. 数据结构2.1 链表节点2.2 head 和 tail 节点基本不变式head 的不变式和可变式tail 的不变式和可变式3. 构造函数4. 入队4.1 源码原创 2021-03-29 23:20:03 · 518 阅读 · 0 评论 -
阅读 JDK 源码:传递队列 SynchronousQueue
SynchronousQueue 是一个由链表或栈结构组成的阻塞队列,适用于传递性场景,即生产者线程处理的数据直接传递给消费者线程。队列中不直接存储数据元素(队列容量固定为 0)。采用无锁算法,每个线程的存入或取出操作没有被匹配时,将会阻塞在队列中等待匹配,内部的链表或栈结构用于暂存阻塞的线程。当消费者消费速度赶不上生产速度,队列会阻塞严重。文章目录1. 继承体系2. 数据结构3. 构造函数4. 属性5. 容量6. 存入取出操作7. 栈实现栈定义节点定义transferawaitFulfill8. 队列原创 2021-03-29 22:35:02 · 122 阅读 · 0 评论 -
阅读 JDK 源码:WeakHashMap 和 Reference、ReferenceQueue
WeakHashMap 是一种特殊的 HashMap,它的 key 为 WeakReference 弱引用,并且内置了一个 ReferenceQueue 用于存储被回收的弱引用。阅读 WeakHashMap 源码之前,需要先理解 Reference 和 ReferenceQueue 的机制。理解其基本原理之后,可以使用 HashMap 达到跟 WeakHashMap 一样的效果,文末提供了示例。1. Referencepublic abstract class Reference<T>ex原创 2021-03-19 09:31:32 · 550 阅读 · 0 评论 -
阅读 JDK 源码:ConcurrentHashMap 扩容总结 (发现源码的BUG!)
这段时间阅读了 JDK 8 的 ConcurrentHashMap 源码,其中扩容的过程涉及技术点繁多,很有必要自己动手对扩容原理进行梳理总结。本文中,我对关键代码编写了单元测试,并且找来了图例,方便理解。编写文章过程,我竟然发现了 JDK 8 版本扩容时对 sizeCtl 的判断有 BUG,具体在第 3.4 节中说明。1. 数据结构使用数组+链表+红黑树来实现,利用 CAS + synchronized 来保证并发更新的安全。1.1 对比 Java7与 Java7 相比,Java8 中的 Co原创 2021-03-03 00:32:38 · 742 阅读 · 2 评论 -
阅读 JDK 源码:HashMap 扩容总结及图解
本文基于 Java8,通过阅读 HashMap 的 resize 方法了解其扩容原理,并对桶上链表的迁移过程进行调试,画图以加深理解。文章目录1. 扩容的时机2. 扩容的源码如果是链结构如果是树结构3. 链表迁移算法执行结果执行过程图示4. 总结1. 扩容的时机HashMap 中 put 入第一个元素,初始化数组 table。HashMap 中的元素数量大于阈值 threshold。threshold = capacity * load factor。当 size > thresho原创 2021-03-01 09:36:00 · 7997 阅读 · 0 评论 -
HashMap 中的取模和扩容公式推导
为什么 HashMap 容量 capacity 大小是 2 的 n 次幂?为什么使用 e.hash & (capacity - 1) 位运算作取模公式?为什么扩容时使用 e.hash & oldCap 来计算扩容后的数组索引?本文通过推导 HashMap 中的取模和扩容算法以回答上述问题。文章目录1. 按位与(&)运算的理解2. 取模运算2.1 当 e.hash 为正数2.2 当 e.hash 为负数负数取模怎么算整数除法取整取模怎么算3. 扩容运算3.1 推导 e.ha.原创 2021-02-27 09:55:42 · 1836 阅读 · 3 评论