说到HashMap,就一定要说到红黑树,红黑树作为一种自平衡二叉查找树,是一种用途较广的数据结构,在jdk1.8中使用红黑树提升HashMap的性能,今天就来说一说红黑树,上一讲已经给出插入平衡的调整操作,这一讲就说说更为复杂的删除平衡操作. 前言 限于篇幅,本文只对红黑树的基础进行说明,暂不涉及源码部分,大部分摘抄自维基百科,这里也贴出对应链接: 维基百科(中文):https://zh.wikipedia.org/wiki/%E7%BA%A2%E9%BB%91%E6%A0%91 维基百科:ht…
说到HashMap,就一定要说到红黑树,红黑树作为一种自平衡二叉查找树,是一种用途较广的数据结构,在jdk1.8中使用红黑树提升HashMap的性能,今天就来说一说红黑树. 前言 限于篇幅,本文只对红黑树的基础进行说明,暂不涉及源码部分,大部分摘抄自维基百科,这里也贴出对应链接: 维基百科(中文):https://zh.wikipedia.org/wiki/%E7%BA%A2%E9%BB%91%E6%A0%91 维基百科:https://en.wikipedia.org/wiki/Red%E2%…
前面几篇文章已经讲解过HashMap内部实现以及红黑树的基础知识,今天这篇文章就讲解之前HashMap中未讲解的红黑树操作部分,如果没了解红黑树,请去阅读前面的两篇文章,能更好的理解本章所讲解的红黑树源码操作,全文默认读者已经了解红黑树的相关知识,接下来,就以HashMap.TreeNode来说明红黑树的源码操作. 前言 jdk版本:1.8 以HashMap.TreeNode为例是因为之前HashMap的红黑树操作在文章省略了,这里进行一个解释,其实源码里并不是只有这个地方用红黑树结构,但是总体…
前面已经说明了HashMap以及红黑树的一些基本知识,对JDK8的HashMap也有了一定的了解,本篇就开始看看并发包下的ConcurrentHashMap,说实话,还是比较复杂的,笔者在这里也不会过多深入,源码层次上了解一些主要流程即可,清楚多线程环境下整个Map的运作过程就算是很大进步了,更细的底层部分需要时间和精力来研究,暂不深入 前言 jdk版本:1.8 JDK7中,ConcurrentHashMap把内部细分成了若干个小的HashMap,称之为段(Segment),默认被分为16个段.…
源码部分从HashMap说起是因为笔者看了很多遍这个类的源码部分,同时感觉网上很多都是粗略的介绍,有些可能还不正确,最后只能自己看源码来验证理解,写下这篇文章一方面是为了促使自己能深入,另一方面也是给一些新人一些指导,不求有功,但求无过.有错误的地方请在评论中指出,我会及时验证修改,谢谢. 接下来就来说下我眼中的HashMap. jdk版本:1.8 在深入源码之前,了解HashMap的整体结构是非常重要的事情,结构也体现出了源码中一些对HashMap的操作,结构大致如下: 从上边的结构图大家应该…
JAVA中多线程的操作对于初学者而言是比较难理解的,其实联想到底层操作系统时我们可能会稍微明白些,对于程序而言最终都是硬件上运行二进制指令,然而,这些又太过底层,今天来看一下JAVA中的线程,浅析JDK源码中的Thread类,之后能帮助我们更好的处理线程问题 前言 JDK版本号:1.8.0_171 在Thread注释中可以看到大佬对其进行的解释: Thread就是程序中一个线程的执行.JVM允许一个应用中多个线程并发执行 每个线程都有优先级.高优先级线程优先于低优先级线程执行 每个线程都可以(不…
前面已经讲解集合中的HashMap并且也对其中使用的红黑树结构做了对应的说明,这次就来看下简单一些的另一个集合类,也是日常经常使用到的ArrayList,整体来说,算是比较好理解的集合了,一起来看下 前言 jdk版本:1.8 类定义 public class ArrayList<E> extends AbstractList<E> implements List<E>, RandomAccess, Cloneable, java.io.Serializable 继承了A…
(这篇文章暂时鸽了,有点理解不能,点进来的小伙伴可以撤了) 刚开始准备在HashMap中直接把红黑树也过了的,结果发现这个类不是一般的麻烦,所以单独开一篇. 由于红黑树之前完全没接触过,所以这篇博客相当于探索(其实之前的博客都是边看源码边写的,全是探索). 红黑树没见过,树我还是知道的,所以先上一张帅图: 红黑树在这个基本树的基础上还多了red,暂时不知道啥意思,慢慢探索. 先来一个类总览: static final class TreeNode<K,V> extends LinkedHash…
上一篇文章已经就ConcurrentHashMap进行了部分说明,介绍了其中涉及的常量和变量的含义,有些部分需要结合方法源码来理解,今天这篇文章就继续讲解并发ConcurrentHashMap 前言 本文主要介绍ConcurrentHashMap中的一些重要方法,结合上篇文章中的讲解部分进行更进一步的介绍 回顾下上篇文章,我们应该已经知道ConcurrentHashMap的整体结构和HashMap基本一致,不同的是处理多线程并发下保证操作的正确性,ConcurrentHashMap通过CAS和s…
非阻塞队列ConcurrentLinkedQueue我们已经了解过了,既然是Queue,那么是否有其双端队列实现呢?答案是肯定的,今天就继续说一说非阻塞双端队列实现ConcurrentLinkedDeque 前言 JDK版本号:1.8.0_171 ConcurrentLinkedDeque是一个基于链表实现的无界的线程安全的同时支持FIFO.LIFO非阻塞双端队列.操作上可类比ConcurrentLinkedQueue,利用CAS进行无锁操作,同时通过松弛度阈值设置来减少CAS操作,在理解这个类…
阻塞队列的实现前面已经讲解完毕,今天我们继续了解源码中非阻塞队列的实现,接下来就看一看ConcurrentLinkedQueue非阻塞队列是怎么完成操作的 前言 JDK版本号:1.8.0_171 ConcurrentLinkedQueue是一个基于链表实现的无界的线程安全的FIFO非阻塞队列.最大的不同之处在于非阻塞特性,不会进行阻塞等待直接返回操作结果.其中head和tail的更新类似之前在LinkedTransferQueue中讲解的slack(松弛度)机制,只有在slack阈值大于等于2时…
阻塞队列中目前还剩下一个比较特殊的队列实现,相比较前面讲解过的队列,本文中要讲的LinkedBlockingDeque比较容易理解了,但是与之前讲解过的阻塞队列又有些不同,从命名上你应该能看出一些端倪,接下来就一起看看这个特殊的阻塞队列 前言 JDK版本号:1.8.0_171 LinkedBlockingDeque在结构上有别于之前讲解过的阻塞队列,它不是Queue而是Deque,中文翻译成双端队列,双端队列指可以从任意一端入队或者出队元素的队列,实现了在队列头和队列尾的高效插入和移除 Link…
在JDK8的阻塞队列实现中还有两个未进行说明,今天继续对其中的一个阻塞队列LinkedTransferQueue进行源码分析,如果之前的队列分析已经让你对阻塞队列有了一定的了解,相信本文要讲解的LinkedTransferQueue的源码也能很快被理解,接下来一起学习吧 前言 JDK版本号:1.8.0_171 LinkedTransferQueue是基于链表的FIFO无界阻塞队列,在源码分析前,需要提前对源码实现整体有个印象,便于细节的理解.注释部分对于这个类进行了一些说明和介绍,如果有能力的话…
作为阻塞队列的一员,DelayQueue(延迟队列)由于其特殊含义而使用在特定的场景之中,主要在于Delay这个词上,那么其内部是如何实现的呢?今天一起通过DelayQueue的源码来看一看其是如何完成Delay操作的 前言 JDK版本号:1.8.0_171 DelayQueue内部通过优先级队列PriorityQueue来实现队列元素的排序操作,之前已经介绍过PriorityBlockingQueue的源码实现,两者比较类似,可自行回顾下,既然用到了优先级队列,则需要保证其队列元素的可比较性,…
今天继续来讲解阻塞队列,一个比较特殊的阻塞队列SynchronousQueue,通过Executors框架提供的线程池cachedThreadPool中我们可以看到其被使用作为可缓存线程池的队列实现,下面通过源码来了解其内部实现,便于后面帮助我们更好的使用线程池 前言 JDK版本号:1.8.0_171 synchronousQueue是一个没有数据缓冲的阻塞队列,生产者线程的插入操作put()必须等待消费者的删除操作take(),反过来也一样.当然,也可以不进行等待直接返回,例如poll和off…
今天继续说一说阻塞队列的实现,今天的主角就是优先级阻塞队列PriorityBlockingQueue,从命名上看觉得应该是有序的,毕竟是优先级队列,那么实际上是什么情况,我们一起看下其内部实现,提前说明下,因为PriorityBlockingQueue涉及到了堆排序的相关使用,如果没了解清楚,可以参考我之前写的关于堆排序的相关说明 前言 JDK版本号:1.8.0_171 PriorityBlockingQueue是一个无限容量的阻塞队列,当然,最终还是受内存限制,内部实现是数组,不停增长下去会导…
今天继续讲解阻塞队列,涉及到了常用线程池的其中一个队列LinkedBlockingQueue,从类命名部分我们就可以看出其用意,队列中很多方法名是通用的,只是每个队列内部实现不同,毕竟实现的都是同一个接口BlockingQueue,可以自行查看接口源码,下面我们一起看下LinkedBlockingQueue实现的源码部分 前言 JDK版本号:1.8.0_171 LinkedBlockingQueue是链表实现的线程安全的无界的阻塞队列 内部是通过Node节点组成的链表来实现的 线程安全说明的是内…
线程在JDK中是非常重要的一块内容,所有的应用服务都离不开线程的相关操作,对于大量线程的使用都是推荐使用线程池来进行操作和管理,JDK本身提供的线程池在服务中经常被使用到,以往经常使用Executors来创建,但是阿里规范中也指出了其存在的隐患,从源码来看,内部大量使用了队列相关的类,所以在深入线程部分之前,我们需要了解队列相关的内容,本文就以ArrayBlockingQueue开始对JDK中的常用的队列进行说明 前言 首先我们需要明白其结构特点:ArrayBlockingQueue是数组实现的…
之前一篇文章已经讲解了阻塞队列SynchronousQueue的大部分内容,其中默认的非公平策略还未说明,本文就紧接上文继续讲解其中的非公平策略下的内部实现,顺便简单说明其涉及到的线程池部分的使用 前言 回顾一下,SynchronousQueue通过两个内部类实现了公平策略和非公平策略的无缓存阻塞队列,每种操作都需要对应的互补操作同时进行才能完成,例如,入队操作必然对应出队操作,在不涉及超时和中断的情况下,必须等待另一个线程进行出队操作,两两匹配才能执行,否则就阻塞等待 之前已经对公平策略下的内…
概况 Java的Short类主要的作用就是对基本类型short进行封装,提供了一些处理short类型的方法,比如short到String类型的转换方法或String类型到short类型的转换方法,当然也包含与其他类型之间的转换方法. 继承结构 --java.lang.Object --java.lang.Number --java.lang.Short 主要属性 public static final short MIN_VALUE = -32768; public static final s…
Java的Byte类主要的作用就是对基本类型byte进行封装,提供了一些处理byte类型的方法,比如byte到String类型的转换方法或String类型到byte类型的转换方法,当然也包含与其他类型之间的转换方法. 主要实现代码如下: public final class Byte extends Number implements Comparable<Byte> { public static final byte MIN_VALUE = -128; public static fina…
红黑树遵循的条件: 1.根节点为黑色. 2.外部节点(叶子节点)为黑色. 3.红色节点的孩子节点为黑色.(由此,红色节点的父节点也必为黑色) 4.从根节点到任一外部节点的路径上,黑节点的数量相同. 节点插入过程  在红黑树中插入节点,首先调用查找接口,并在查找终止位置创建节点,并将节点染成红色.  当新插入节点的父节点为红色时,不满足红黑树的条件,产生'双红'现象.此时,需要对树的拓扑结构和节点颜色进行调节. 双黑修正过程  以JDK TreeMap.class 中定义的红黑树类中插入修正函数为…
最近在整理JAVA 基础知识,从jdk源码入手,今天就jdk中 java.util包下集合类进行理解 先看图 从类图结构可以了解 java.util包下的2个大类: 1.Collecton:可以理解为主要存放的是单个对象 2.Map:可以理解为主要存储key-value类型的对象 一.Collection Collection继承了Iterate接口,Iterate用于集合内迭代器抽象接口,其子类均实现接口中方法,看下ArrayList下实现: /** * Returns an iterator…
置顶一篇文章,主要是整理一下写过的JDK中各个类的源码及其他框架源码解析的文章,方便自己随时阅读也方便网友朋友们阅读与指正 基础篇 从为什么String=String谈到StringBuilder和StringBuffer Java语法糖1:可变长度参数以及foreach循环原理 Java语法糖2:自动装箱和自动拆箱 集合篇 图解集合1:ArrayList 图解集合2:LinkedList 图解集合3:CopyOnWriteArrayList 图解集合4:HashMap 图解集合5:不正确地使用…
简介 这篇文章主要讲述jdk本身的源码该如何阅读,关于各种框架的源码阅读我们后面再一起探讨. 笔者认为阅读源码主要包括下面几个步骤. 设定目标 凡事皆有目的,阅读源码也是一样. 从大的方面来说,我们阅读源码的目的是为了提升自己的技术能力,运用到工作中,遇到问题快速定位,升职加薪等等. 从小的方面来说,阅读某一段源码的目的就是要搞清楚它的原理,就是死磕,就是那种探索真相的固执. 目的是抽象的,目标是具体的,我们阅读源码之前一定要给自己设定一个目标. 比如,下一章我们将要一起学习的Concurren…
  很多java开发的小伙伴都会阅读jdk源码,然而确不知道应该从哪读起.以下为小编整理的通常所需阅读的源码范围. 标题为包名,后面序号为优先级1-4,优先级递减 1.java.lang 1) Object 1 2) String 1 3) AbstractStringBuilder 1 4) StringBuffer 1 5) StringBuilder 1 6) Boolean 2 7) Byte 2 8) Double 2 9) Float 2 10) Integer 2 11) Long…
这是看过的第一个jdk源码(从立下目标以来):TreeMap.说实话断断续续的看了有好几天了,我觉得我犯了一个错误,就像一开始说的那样,我打算完完全全看懂TreeMap关于红黑树的实现方式,后来我想了想,相对于花费这个对我的收益并不是特别大,而且看的过程中也有很多困惑,虽然我知道它每一步在做什么,但是我还不知道为什么要这么做,经过权衡,我决定先暂时放下TreeMap中关于对红黑树具体的实现,暂且记下有这回事. 一.简单理解 最近也在看数据结构和算法,对红黑树也有了大致的理解,TreeMap是对红…
概述 前文「JDK源码分析-HashMap(1)」分析了 HashMap 主要方法的实现原理(其他问题以后分析),本文分析下 LinkedHashMap. 先看一下 LinkedHashMap 的类继承结构图: 可以看到 LinkedHashMap 继承了 HashMap. 我们知道 HashMap 是无序的,即迭代器的顺序与插入顺序没什么关系.而 LinkedHashMap 在 HashMap 的基础上增加了顺序:分别为「插入顺序」和「访问顺序」.即遍历 LinkedHashMap 时,可以保…
概述 HashMap 是 Java 开发中最常用的容器类之一,也是面试的常客.它其实就是前文「数据结构与算法笔记(二)」中「散列表」的实现,处理散列冲突用的是“链表法”,并且在 JDK 1.8 做了优化,当链表长度达到一定数量时会把链表转为红黑树. 因此,JDK 1.8 中的 HashMap 实现可以理解为「数组 + 链表 + 红黑树」.内部结构示意图: HashMap 的继承结构和类签名如下: public class HashMap<K,V> extends AbstractMap<…
前文「JDK源码分析-TreeMap(1)」分析了 TreeMap 的一些方法,本文分析其中的增删方法.这也是红黑树插入和删除节点的操作,由于相对复杂,因此单独进行分析. 插入操作 该操作其实就是红黑树的插入节点操作.前面分析过,红黑树是一种平衡二叉树,新增节点后可能导致其失去平衡,因此需要对其进行修复操作以维持其平衡性.插入操作的代码如下: public V put(K key, V value) { Entry<K,V> t = root; // 若 root 节点为空,则直接插入(为根节…