并发永远是高性能的话题,而并发容器又是java中重要的并发工具,所以今天我们来分析一下Concurrent包中ConcurrentHashMap(以下简称Chashmap).普通容器在某些并发情况下的表现很差,假设这容器的体积很大,容器获得锁后进行了非常耗时的遍历操作,那么锁就会被占用很长世间.事实上只有很小一部分元素被线程占用,其余的元素完全可以被读写.而(以下简称Chashmap就是实现了这一特性,使用该容器一部分区域的时候其他线程可以同时读写容器中的剩余区域,所以Chashmap的效率很高…
本文从JDK源码包中截取出concurrent包的所有类,对该包整体结构进行一个概述. 在JDK1.5之前,Java中要进行并发编程时,通常需要由程序员独立完成代码实现.当然也有一些开源的框架提供了这些功能,但是这些框架依然没有JDK自带的功能使用起来方便. 而当针对高质量Java多线程并发程序设计时,比如使用Java之前的wait().notify()和synchronized等,需要考虑性能.死锁.公平性.资源管理以及如何避免线程安全性方面带来的危害等诸多因素,往往会采用一些较为复杂的安全策…
JAVA中多线程的操作对于初学者而言是比较难理解的,其实联想到底层操作系统时我们可能会稍微明白些,对于程序而言最终都是硬件上运行二进制指令,然而,这些又太过底层,今天来看一下JAVA中的线程,浅析JDK源码中的Thread类,之后能帮助我们更好的处理线程问题 前言 JDK版本号:1.8.0_171 在Thread注释中可以看到大佬对其进行的解释: Thread就是程序中一个线程的执行.JVM允许一个应用中多个线程并发执行 每个线程都有优先级.高优先级线程优先于低优先级线程执行 每个线程都可以(不…
简介 这篇文章主要讲述jdk本身的源码该如何阅读,关于各种框架的源码阅读我们后面再一起探讨. 笔者认为阅读源码主要包括下面几个步骤. 设定目标 凡事皆有目的,阅读源码也是一样. 从大的方面来说,我们阅读源码的目的是为了提升自己的技术能力,运用到工作中,遇到问题快速定位,升职加薪等等. 从小的方面来说,阅读某一段源码的目的就是要搞清楚它的原理,就是死磕,就是那种探索真相的固执. 目的是抽象的,目标是具体的,我们阅读源码之前一定要给自己设定一个目标. 比如,下一章我们将要一起学习的Concurren…
通过阅读源码发现,HashSet底层的实现源码其实就是调用HashMap的方法实现的,所以如果你阅读过HashMap或对HashMap比较熟悉的话,那么阅读HashSet就很轻松,也很容易理解了.我之前也写了一篇关于hashMap源码阅读的文章,可以点击这里查看. 使用过HashSet的都清楚它保存的元素是不可以重复的,其实HashSet的元素都是保存在HashMap的key中的,而HashMap的key是没有重复的. 构造函数 /** * Constructs a new, empty set…
  很多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…
今天来看一下ArrayList的源码 目录 介绍 继承结构 属性 构造方法 add方法 remove方法 修改方法 获取元素 size()方法 isEmpty方法 clear方法 循环数组 1.介绍 一般来讲文章开始应该先介绍一下说下简介.这里就不介绍了 如果你不知道ArrayList是什么的话就没必要在看了.大致讲一下一些常用的方法 2.继承结构 ArrayList源码定义: ArrayList继承结构如下: Serializable 序列化接口 Cloneable 前面我们在看Object源…
最近经过某大佬的建议准备阅读一下JDK的源码来提升一下自己 所以开始写JDK源码分析的文章 阅读JDK版本为1.8 目录 Object结构图 构造器 equals 方法 getClass 方法 hashCode 方法 toString 方法 finalize 方法 registerNatives 方法 1. Object结构图 2. 类构造器   类构造器是创建Java对象的方法之一.一般我们都使用new关键字来进行实例,还可以在构造器中进行相应的初始化操作.   在一个Java类中必须存在一个…
JDK源码阅读笔记: https://github.com/kangjianwei/LearningJDK 如何阅读源码,是每个程序员需要面临的一项挑战. 为什么需要阅读源码?从实用性的角度来看,主要有三个目的:第一,解决手头的新问题或者新需求:第二,真正理解一部分理论的落地实现:第三,应对面试. 端正心态 在准备投身到阅读源码的事业之前,首先需要端正一下心态: 阅读源码是一场持久战,浅尝辄止的话,顶多能写几篇水文,吸点粉糊弄下新手,对自身实力的提高没有显著作用. 阅读源码是锦上添花,不是雪中送…
简介 大家好,我是彤哥,今天我想和大家再聊聊JDK源码的几个问题: 为什么要看JDK源码 JDK源码的阅读顺序 JDK源码的阅读方法 为什么要看JDK源码 一,JDK源码是其它所有源码的基础,看懂了JDK源码再看其它的源码会达到事半功倍的效果. 二,JDK源码中包含大量的数据结构知识,是学习数据结构很好的资料,比如,链表.队列.散列表.红黑树.跳表.桶.堆.双端队列等. 三.JDK源码中包含大量的设计模式,是学习设计模式很好的资料,比如,适配器模式.模板方法模式.装饰器模式.迭代器模式.代理模式…
阅读Java源码的前提条件: 1.技术基础 在阅读源码之前,我们要有一定程度的技术基础的支持. 假如你从来都没有学过Java,也没有其它编程语言的基础,上来就啃<Core Java>,那样是很难有收获的,尤其是<深入Java虚拟机>这类书,或许别人觉得好,但是未必适合现在的你. 比如设计模式,许多Java源码当中都会涉及到.再比如阅读Spring源码的时候,势必要先对IOC,AOP,Java动态代理等知识点有所了解. 2.强烈的求知欲 强烈的求知欲是阅读源码的核心动力! 大多数程序…
利用IDEA搭建JDK源码阅读环境 首先新建一个java基础项目 基础目录 source 源码 test 测试源码和入口 准备JDK源码 下图框起来的路径就是jdk的储存位置 打开jdk目录,找到src.zip右键选解压 解压后进入src文件夹,选择java.javax.org 复制 粘贴到 项目的source目录下 注意注意!window系统不要在IDEA里面复制,而是像下图直接在文件夹之间复制. 源码准备完毕 解除Debug限制 取消勾选单步进入底层类 更换SourcePath 原来的源码是…
本文转载自JDK源码阅读-FileInputStream 导语 FileIntputStream用于打开一个文件并获取输入流. 打开文件 我们来看看FileIntputStream打开文件时,做了什么操作: public FileInputStream(File file) throws FileNotFoundException { String name = (file != null ? file.getPath() : null); SecurityManager security =…
本文转载自JDK源码阅读-ByteBuffer 导语 Buffer是Java NIO中对于缓冲区的封装.在Java BIO中,所有的读写API,都是直接使用byte数组作为缓冲区的,简单直接.但是在Java NIO中,缓冲区这一概念变得复杂,可能是对应Java堆中的一块内存,也可能是对应本地内存中的一块内存.而byte数组只能用来指定Java堆中的一块内存,所以Java NIO中设计了一个新的缓冲区抽象,涵盖了不同类型缓冲区,这个抽象就是Buffer. Buffer Buffer是Java NI…
本文转载自JDK源码阅读-RandomAccessFile 导语 FileInputStream只能用于读取文件,FileOutputStream只能用于写入文件,而对于同时读取文件,并且需要随意移动文件当前偏移量的话,就需要使用RandomAccessFile这个类了.RandomAccessFile是对操作系统提供的文件读写能力最完整的封装. 打开文件 RAF打开文件时,除了指定文件对象,还需要指定一个模式,取值有: "r" 以只读方式打开.调用结果对象的任何 write 方法都将…
本文转载自JDK源码阅读-FileDescriptor 导语 操作系统使用文件描述符来指代一个打开的文件,对文件的读写操作,都需要文件描述符作为参数.Java虽然在设计上使用了抽象程度更高的流来作为文件操作的模型,但是底层依然要使用文件描述符与操作系统交互,而Java世界里文件描述符的对应类就是FileDescriptor. Java文件操作的三个类:FileIntputStream,FileOutputStream,RandomAccessFile,打开这些类的源码可以看到都有一个FileDe…
本文转载自JDK源码阅读-Reference 导语 Java最初只有普通的强引用,只有对象存在引用,则对象就不会被回收,即使内存不足,也是如此,JVM会爆出OOME,也不会去回收存在引用的对象. 如果只提供强引用,我们就很难写出"这个对象不是很重要,如果内存不足GC回收掉也是可以的"这种语义的代码.Java在1.2版本中完善了引用体系,提供了4中引用类型:强引用,软引用,弱引用,虚引用.使用这些引用类型,我们不但可以控制垃圾回收器对对象的回收策略,同时还能在对象被回收后得到通知,进行相…
本文转载自JDK源码阅读-DirectByteBuffer 导语 在文章JDK源码阅读-ByteBuffer中,我们学习了ByteBuffer的设计.但是他是一个抽象类,真正的实现分为两类:HeapByteBuffer与DirectByteBuffer.HeapByteBuffer是堆内ByteBuffer,使用byte[]存储数据,是对数组的封装,比较简单.DirectByteBuffer是堆外ByteBuffer,直接使用堆外内存空间存储数据,是NIO高性能的核心设计之一.本文来分析一下Di…
本文转载自JDK源码阅读-FileOutputStream 导语 FileOutputStream用户打开文件并获取输出流. 打开文件 public FileOutputStream(File file, boolean append) throws FileNotFoundException { String name = (file != null ? file.getPath() : null); SecurityManager security = System.getSecurityM…
下面说明在Netbeans.Eclipse环境下怎么查看JDK源码: Netbeans: 在"工具->java平台->源"里添加下路径,如果你安装jdk的时候选择安装了源码的话,jdk目录里会有一个src.zip的文件,添加这个文件就可以了. 选中相应的代码,ctrl+鼠标左键.就进入到源码环境了. Eclipse: 1.点 "window"-> "Preferences" -> "Java" ->…
序 如同C语言中字符数组向String过渡一样,作为面向对象语言,自然而然的出现了由Object[]数据形成的集合.本文从JDK源码出发简单探讨一下ArrayList的几个重要方法. Fields //序列化Id保证了集合是可以进行RPC通信的 private static final long serialVersionUID = 8683452581122892189L; //作为一个普通Object[]数组,集合的默认长度是10 private static final int DEFAU…
前面已经说明了HashMap以及红黑树的一些基本知识,对JDK8的HashMap也有了一定的了解,本篇就开始看看并发包下的ConcurrentHashMap,说实话,还是比较复杂的,笔者在这里也不会过多深入,源码层次上了解一些主要流程即可,清楚多线程环境下整个Map的运作过程就算是很大进步了,更细的底层部分需要时间和精力来研究,暂不深入 前言 jdk版本:1.8 JDK7中,ConcurrentHashMap把内部细分成了若干个小的HashMap,称之为段(Segment),默认被分为16个段.…
前言 先预先说明,我这边jdk的代码版本为1.8.0_11,同时,因为我直接在本地jdk源码上进行了部分修改.调试,所以,导致大家看到的我这边贴的代码,和大家的不太一样. 不过,我对源码进行修改.重构时,会保证和原始代码的功能.逻辑严格一致,更多时候,可能只是修改变量名,方便理解. 大家也知道,jdk代码写得实在是比较深奥,变量名经常都是单字符,i,j,k啥的,实在是很难理解,所以,我一般会根据自己的理解,去重命名,为了减轻我们的头脑负担. 至于怎么去修改代码并调试,可以参考我之前的文章: 曹工…
曹工说JDK源码(1)--ConcurrentHashMap,扩容前大家同在一个哈希桶,为啥扩容后,你去新数组的高位,我只能去低位? 曹工说JDK源码(2)--ConcurrentHashMap的多线程扩容,说白了,就是分段取任务 曹工说JDK源码(3)--ConcurrentHashMap,Hash算法优化.位运算揭秘 什么是缓存雪崩 基本概念梳理 这个基本也是redis 面试的经典题目了,然而,网上不少博客对这个词的定义都含糊不清,各执一词. 主要有两类说法: 大量缓存key,由于设置了相同…
(一)集合框架: Java语言的设计者对常用的数据结构和算法做了一些规范(接口)和实现(实现接口的类).所有抽象出来的数据结构和操作(算法)统称为集合框架. 程序员在具体应用的时候,不必考虑数据结构和算法实现细节,只需要用这些类创建一些对象,然后直接应用就可以了,这样就大大提高了编程效率. (二)集合框架包含的内容: (三)集合框架的接口(规范)   Collection接口:存储一组不唯一,无序的对象 List接口:存储一组不唯一,有序的对象 Set接口:存储一组唯一,无序的对象 Map接口:…
一.概述 ConcurrentHashMap是Java5中新增加的一个线程安全的Map集合,可以用来替代HashTable. 锁分段技术 原理:将数据分成一段一段的存储,然后给每一段数据配一把锁,当一个线程占用锁访问其中一个段数据的时候,其他段的数据也能被其他线程访问. 理解Java存储模型(JMM)的Happens-Before规则 一个例子 public class Test1 { private int a=1, b=2; public void foo(){ // 线程1 a=3; b=…
JUC源码分析-其它工具类(一)ThreadLocalRandom ThreadLocalRandom 是 JDK7 在 JUC 包下新增的随机数生成器,它解决了 Random 在多线程下多个线程竞争内部唯一的原子性种子变量而导致大量线程自旋重试的不足.需要注意的是 Random 本身是线程安全的.同时 Random 实例不是安全可靠的加密,可以使用 java.security.SecureRandom 来提供一个可靠的加密. 1. 随机数算法介绍 常用的随机数算法有两种:同余法(Congrue…
前文「JDK源码分析-HashMap(1)」分析了 HashMap 的内部结构和主要方法的实现原理.但是,面试中通常还会问到很多其他的问题,本文简要分析下常见的一些问题. 这里再贴一下 HashMap 内部的结构图(JDK 1.8): FAQ Q1: HashMap 是否线程安全?为什么? 首先 HashMap 是线程不安全的.这一点很多人应该都了解,HashMap 源码中也有说明.但是为什么说不安全?体现在哪里呢?下面通过两个例子简要进行分析(可能不够全面,仅做参考). case 1: 线程…
JDK源码学习String篇中,有一处错误,String类用final[不能被改变的]修饰,而我却写成静态的,感谢CTO-淼淼的指正. 风一样的码农提出的String为何采用final的设计,阅读JDK源码的时候,有粗略的思考过,今天下班后又把<Thinking in Java>中关于final的内容重新看了一遍,对此写下一些关于自己的理解和想法. String类中final关键字的使用 final关键字,用来描述一块数据不能被改变,两种可能理由:设计.效率 final使用的三种情况:数据.方…
使用java开发,如果能阅读JDK的经典代码,对自己的水平提高是很有帮助的.笔者在实际工作中总结了两种阅读JDK源码的方式.第一种下载android源代码,直接在android源码代码中,这里的代码虽然不是标准的JDK源码,但是也很不错值得一看.另外一种,就是笔者接触java之后一直使用的方式,直接访问JDK源码,无须下载其他文件.       步骤一:在eclipse中,按住Ctrl+鼠标右键访问String类        步骤二:在eclipse打开的空白页中选择change Attach…