JDK源码分析
JDK源码分析
老猿说说
Java老猿
展开
-
线程池面试题
#md#1 面试题1.1 创建子线程时,子线程是得不到父线程的 ThreadLocal,有什么办法可以解决这个问题?答:这道题主要考察线程的属性和创建过程,可以这么回答。可以使用 InheritableThreadLocal 来代替 ThreadLocal,ThreadLocal 和 InheritableThreadLocal 都是线程的属性,所以可以做到线程之间的数据隔离,在多线程环境下我们经常使用,但在有子线程被创建的情况下,父线程 ThreadLocal 是无法传递给子线程的,但 Inhe原创 2020-12-22 09:43:44 · 47582 阅读 · 0 评论 -
Future、ExecutorService
1 整体架构画了一个关于线程 API 之间关系的依赖图,如下:在上一章节,我们说了 Thread 和 Runnable,本小节我们按照这个图把剩下的几个 API 也说完,然后把 API 之间的关系理清楚。为了方便大家更好的理解,我们首先看一个 demo,这个场景说的是我们往线程池里面提交一个有返回值的线程,代码如下:// 首先我们创建了一个线程池ThreadPoolExecutor executor = new ThreadPoolExecutor(3, 3, 0L, TimeUnit.MILL原创 2020-12-22 09:36:47 · 46884 阅读 · 0 评论 -
老猿说说-Thread
引导语从本章开始我们开始学习线程的知识,线程是非常有趣的一个章节,大多数同学对于线程 API,属于不用就忘,到用时需要百度的情况,希望通过本小节的源码阅读,能够加深对线程的印象。本小节主要三章,本章主要说线程的基本概念、使用姿势、Thread 和 Runnable 的源码;Future、ExecutorService 源码解析章节主要说异步线程执行;押宝线程源码面试题章节主要说说常遇到的源码面试题。由于线程的概念很多,所以本章会先介绍很多线程的基本概念,说清楚后再解析源码,不然有些同学会看不懂,大家见原创 2020-11-24 10:12:11 · 45894 阅读 · 0 评论 -
队列面试题
1 面试题1.1 说说你对队列的理解,队列和集合的区别。答:对队列的理解:首先队列本身也是个容器,底层也会有不同的数据结构,比如 LinkedBlockingQueue 是底层是链表结构,所以可以维持先入先出的顺序,比如 DelayQueue 底层可以是队列或堆栈,所以可以保证先入先出,或者先入后出的顺序等等,底层的数据结构不同,也造成了操作实现不同;部分队列(比如 LinkedBlockingQueue )提供了暂时存储的功能,我们可以往队列里面放数据,同时也可以从队列里面拿数据,两者可以同时进原创 2020-11-24 10:03:49 · 46364 阅读 · 0 评论 -
老猿说说-SynchronousQueue
引导语SynchronousQueue 是比较独特的队列,其本身是没有容量大小,比如我放一个数据到队列中,我是不能够立马返回的,我必须等待别人把我放进去的数据消费掉了,才能够返回。SynchronousQueue 在消息队列技术中间件中被大量使用,本文就来从底层实现来看下 SynchronousQueue 到底是如何做到的。1 整体架构SynchronousQueue 的整体设计比较抽象,在内部抽象出了两种算法实现,一种是先入先出的队列,一种是后入先出的堆栈,两种算法被两个内部类实现,而直接对外的原创 2020-11-19 10:06:56 · 122556 阅读 · 5 评论 -
老猿说说-LinkedBlockingQueue
引导语说到队列,大家的反应可能是我从来都没有用过,应该是不重要的 API 吧。如果这么想,那就大错特错了,我们平时使用到的线程池、读写锁、消息队列等等技术和框架,底层原理都是队列,所以我们万万不可轻视队列,队列是很多高级 API 的基础,学好队列,对自己深入 Java 学习非常重要。本文主要以 LinkedBlockingQueue 队列为例,详细描述一下底层具体的实现。1 整体架构LinkedBlockingQueue 中文叫做链表阻塞队列,这个命名很好,从命名上就知道其底层数据结构是链表,并且原创 2020-11-19 09:21:10 · 51422 阅读 · 0 评论 -
老猿说说-CopyOnWriteArrayList
引导语在 ArrayList 的类注释上,JDK 就提醒了我们,如果要把 ArrayList 作为共享变量的话,是线程不安全的,推荐我们自己加锁或者使用 Collections.synchronizedList 方法,其实 JDK 还提供了另外一种线程安全的 List,叫做 CopyOnWriteArrayList,这个 List 具有以下特征:线程安全的,多线程环境下可以直接使用,无需加锁;通过锁 + 数组拷贝 + volatile 关键字保证了线程安全;每次数组操作,都会把数组拷贝一份出来,在新原创 2020-11-17 11:04:25 · 72819 阅读 · 0 评论 -
并发List/Map面试题
#md#1 CopyOnWriteArrayList 相关1.1 和 ArrayList 相比有哪些相同点和不同点?答:相同点:底层的数据结构是相同的,都是数组的数据结构,提供出来的 API 都是对数组结构进行操作,让我们更好的使用。不同点:后者是线程安全的,在多线程环境下使用,无需加锁,可直接使用。1.2 CopyOnWriteArrayList 通过哪些手段实现了线程安全?答:主要有:1. 数组容器被 volatile 关键字修饰,保证了数组内存地址被任意线程修改后,都会通知到其他线程;对原创 2020-11-17 10:41:31 · 38032 阅读 · 0 评论 -
老猿说说-ArrayBlockingQueue
#md#引导语本小节我们来介绍本章最后一个队列:ArrayBlockingQueue。按照字面翻译,中文叫做数组阻塞队列,从名称上看,我们就比较清楚此阻塞队列底层使用的是数组。一说到数组,大家可能会想到 ArrayList 和 HashMap,举新增场景来说 ArrayList 通过 size ++ 找到新增的数组下标位置,HashMap 通过 hash 算法计算出下标位置,那么 ArrayBlockingQueue 是不是也是这两种方法呢?都不是,ArrayBlockingQueue 使用的是一种非常原创 2020-11-16 09:51:12 · 41026 阅读 · 0 评论 -
Map面试问题
引导语Map 在面试中,占据了很大一部分的面试题目,其中以 HashMap 为主,这些面试题目有的可以说得清楚,有的很难说清楚,如果是面对面面试的话,建议画一画。1 Map 整体数据结构类问题1.1 说一说 HashMap 底层数据结构答:HashMap 底层是数组 + 链表 + 红黑树的数据结构,数组的主要作用是方便快速查找,时间复杂度是 O(1),默认大小是 16,数组的下标索引是通过 key 的 hashcode 计算出来的,数组元素叫做 Node,当多个 key 的 hashcode 一致,原创 2020-10-27 16:13:58 · 21973 阅读 · 0 评论 -
DelayQueue
引导语之前我们说的阻塞队列,都是资源足够时立马执行。本章我们说的队列比较特殊,是一种延迟队列,意思是延迟执行,并且可以设置延迟多久之后执行,比如设置过 5 秒钟之后再执行,在一些延迟执行的场景被大量使用,比如说延迟对账等等。1 整体设计DelayQueue 延迟队列底层使用的是锁的能力,比如说要在当前时间往后延迟 5 秒执行,那么当前线程就会沉睡 5 秒,等 5 秒后线程被唤醒时,如果能获取到资源的话,线程即可立马执行。原理上似乎很简单,但内部实现却很复杂,有很多难点,比如当运行资源不够,多个线程同时原创 2020-10-23 10:29:55 · 4880 阅读 · 0 评论 -
老猿说说-TreeMap、LinkedHashMap
引导语在熟悉 HashMap 之后,本小节我们来看下 TreeMap 和 LinkedHashMap,看看 TreeMap 是如何根据 key 进行排序的,LinkedHashMap 是如何用两种策略进行访问的。1 知识储备在了解 TreeMap 之前,我们来看下日常工作中排序的两种方式,作为我们学习的基础储备,两种方式的代码如下:public class TreeMapDemo { @Data // DTO 为我们排序的对象 class DTO implements Compara原创 2020-10-23 09:57:50 · 8882 阅读 · 0 评论 -
List面试题
引导语List 作为工作中最常见的集合类型,在面试过程中,也是经常会被问到各种各样的面试题,一般来说,只要你看过源码,心中对 List 的总体结构和细节有所了解的话,基本问题都不大。1 面试题1.1 说说你自己对 ArrayList 的理解?很多面试官喜欢这样子开头,考察面试同学对 ArrayList 有没有总结经验,介于 ArrayList 内容很多,建议先回答总体架构,再从某个细节出发作为突破口,比如这样:ArrayList 底层数据结构是个数组,其 API 都做了一层对数组底层访问的封装,比原创 2020-10-22 21:29:09 · 12939 阅读 · 0 评论 -
String、Long 源码解析和面试题
引导语String 和 Long 大家都很熟悉,本小节主要结合实际的工作场景,来一起看下 String 和 Long 的底层源码实现,看看平时我们使用时,有无需要注意的点,总结一下这些 API 都适用于哪些场景1 String1.1 不变性我们常常听人说,HashMap 的 key 建议使用不可变类,比如说 String 这种不可变类这里说的不可变指的是类值一旦被初始化,就不能再被改变了,如果被修改,将会是新的类,我们写个 demo 来演示一下String s ="hello";s ="wor原创 2020-10-22 17:40:32 · 9401 阅读 · 0 评论 -
老猿说说-AbstractQueuedSynchronizer(2)
本章我们主要聊下如何释放锁和同步队列两大部分。1 释放锁释放锁的触发时机就是我们常用的 Lock.unLock () 方法,目的就是让线程释放对资源的访问权(流程见整体架构图紫色路线)。释放锁也是分为两类,一类是排它锁的释放,一类是共享锁的释放,我们分别来看下。1.1 释放排它锁 release排它锁的释放就比较简单了,从队头开始,找它的下一个节点,如果下一个节点是空的,就会从尾开始,一直找到状态不是取消的节点,然后释放该节点,源码如下:// unlock 的基础方法public final原创 2020-10-14 09:45:34 · 87597 阅读 · 1 评论 -
老猿说说-AbstractQueuedSynchronizer(1)
引导AbstractQueuedSynchronizer中文翻译叫做同步器,简称AQS,是各种各样锁的基础,比如说 ReentrantLock、CountDownLatch等等,这些我们经常用的锁底层实现都是AQS,所以学好AQS对于后面理解锁的实现是非常重要的。锁章节的内容是这么安排的:AQS源码非常多,我们会分成两个小节来说,先把底层原理弄清楚;我们平时用不到AQS,只会接触到ReentrantLock、CountDownLatch这些锁,我们以两个锁为例子,讲解下源码,因为AQS只要弄原创 2020-10-13 14:40:59 · 138938 阅读 · 0 评论 -
老猿说说-ConcurrentHashMap
1 类注释我们从类注释上大概可以得到如下信息:所有的操作都是线程安全的,我们在使用时,无需再加锁;多个线程同时进行put、remove等操作时并不会阻塞,可以同时进行,和HashTable不同,HashTable在操作时,会锁住整个Map;迭代过程中,即使Map结构被修改,也不会抛ConcurrentModificationException异常;除了数组+链表+红黑树的基本结构外,新增了转移节点,是为了保证扩容时的线程安全的节点;提供了很多Stream流式方法,比如说:forEach、sea原创 2020-10-12 11:36:13 · 38854 阅读 · 0 评论 -
老猿说说-LinkedList
1. 概述LinkedList 其实就是一个双向链表结构链表每个节点我们叫做Node,Node有prev属性,代表前一个节点的位置,next属性,代表后一个节点的位置;first是双向链表的头节点,它的前一个节点是null。last是双向链表的尾节点,它的后一个节点是null;当链表中没有数据时,first和last是同一个节点,前后指向都是null;因为是个双向链表,只要机器内存足够强大,是没有大小限制的。链表中的元素叫做Node,我们看下Node的组成部分: private sta原创 2020-10-11 23:25:25 · 9637 阅读 · 0 评论 -
老猿说说-HashMap
1. 概述HashMap 底层的数据结构主要是:数组 + 链表 + 红黑树。其中当链表的长度大于等于 8 时,链表会转化成红黑树,当红黑树的大小小于等于 6 时,红黑树会转化成链表HashMap是数组结构,数组的元素可能是单个 Node,也可能是个链表, 也可能是个红黑树,比如数组下标索引为 2 的位置就是一个链表,下标索引为 9 的位置对应的 就是红黑树,具体细节我们下文再说1.1 类注释从HashMap的类注释中,我们可以得到如下信息:允许null值,不同于HashTable,是线程不安原创 2020-10-10 10:42:41 · 9244 阅读 · 0 评论 -
老猿说说-ArrayList
1 概述ArrayList 整体架构比较简单,就是一个数组结构比如:长度为10的数组,从1开始计数,index表示数组的下标,从0开始计数,elementData表示数组本身,源码中除了这两个概念,还有以下三个基本概念:DEFAULT_CAPACITY表示数组的初始大小,默认是10,这个数字要记住;size表示当前数组的大小,类型int,没有使用volatile修饰,非线程安全的;modCount统计当前数组被修改的版本次数,数组结构有变动,就会+1。类注释看源码,首先要看类注释,我们看原创 2020-10-09 11:37:04 · 39636 阅读 · 7 评论