0

0

教你正确阅读jdk源代码

little bottle

little bottle

发布时间:2019-04-08 16:47:12

|

2822人浏览过

|

来源于博客园

转载

这篇文章主要讲述jdk本身的源码该如何阅读,关于各种框架的源码阅读我们后面再一起探讨。

笔者认为阅读源码主要包括下面几个步骤。

设定目标

凡事皆有目的,阅读源码也是一样。

从大的方面来说,我们阅读源码的目的是为了提升自己的技术能力,运用到工作中,遇到问题快速定位,升职加薪等等。

从小的方面来说,阅读某一段源码的目的就是要搞清楚它的原理,就是死磕,就是那种探索真相的固执。

目的是抽象的,目标是具体的,我们阅读源码之前一定要给自己设定一个目标。

比如,下一章我们将要一起学习的ConcurrentHashMap,我们可以设定以下目标:

(1)熟悉ConcurrentHashMap的存储结构;

(2)熟悉ConcurrentHashMap中主要方法的实现过程;

(3)探索ConcurrentHashMap中出现的新技术;

提出问题

有了目标之后,我们要试着提出一些问题。

还是以ConcurrentHashMap为例,笔者提出了以下这些问题:

(1)ConcurrentHashMap与HashMap的数据结构是否一样?

(2)HashMap在多线程环境下何时会出现并发安全问题?

(3)ConcurrentHashMap是怎么解决并发安全问题的?

(4)ConcurrentHashMap使用了哪些锁?

(5)ConcurrentHashMap的扩容是怎么进行的?

(6)ConcurrentHashMap是否是强一致性的?

(7)ConcurrentHashMap不能解决哪些问题?

(8)ConcurrentHashMap除了并发安全,还有哪些与HashMap不同的地方,为什么要那么实现?

(8)ConcurrentHashMap中有哪些不常见的技术值得学习?

如何提出问题

很多人会说,我也知道要提出问题,但是该怎么提出问题呢?

这确实是很困难的一件事,笔者认为主要是三点:

(1)问自己

把自己当成面试官问自己,往死里问的那种。

如果问自己问不出几个问题,也不要紧,请看下面。

(2)问互联网

很多问题可能自己也想不到,那就需要上网大概查一下相关的博客,看人家有没有提出什么问题。

ImgGood
ImgGood

免费在线AI照片编辑器

下载

或者,查询相关面试题。

比如,笔者学习ConcurrentHashMap这个类时,上网一查很多都是基于jdk7的,那这时候就可以提出一个问题,jdk8与jdk7中ConcurrentHashMap这个类的实现方式有何不同?jdk8对jdk7作了哪些优化?

(3)不断发现问题

一开始提不出几个问题也不要紧,关键是要看,看了才能发现更多的问题。

带着问题阅读源码,忽略不必要的细节,死磕重要的细节

首先,一定要带着问题阅读源码。

其次,一定要忽略不必要的细节。

再次,一定要死磕重要的细节。

乍一看,后面两步似乎有所矛盾,其实不然,忽略不必要的细节是为了不迷失在源码的世界中,死磕重要的细节是为了弄清楚源码的真相。

这里的细节是忽略还是死磕,主要是看跟问题的相关性。

jdk源码还是比较好阅读的,如果后面看spring的源码,做不到忽略不必要的细节,真的是会迷失的,先埋个伏笔哈~~

举个例子,之前阅读过ArrayList的序列化相关的代码中的readObject()方法。

"s.readInt();"这行是干嘛的?省略行不行?这时候就要去了解序列化相关的知识,然后看看writeObject()里面的实现,这就是要死磕的代码。

"SharedSecrets.getJavaOISAccess().checkArray(s, Object[].class, capacity);"这行又是干嘛的?乍一看,好像是跟权限相关的代码,跟我们的问题“序列化”无关,忽略之,如果实在想知道,先打个标记,等把序列化的问题解决了再来研究这个东西。

private void readObject(java.io.ObjectInputStream s)
        throws java.io.IOException, ClassNotFoundException {
    // 声明为空数组
    elementData = EMPTY_ELEMENTDATA;

    // 读入非transient非static属性(会读取size属性)
    s.defaultReadObject();

    // 读入元素个数,没什么用,只是因为写出的时候写了size属性,读的时候也要按顺序来读
    s.readInt();

    if (size > 0) {
        // 计算容量
        int capacity = calculateCapacity(elementData, size);
        SharedSecrets.getJavaOISAccess().checkArray(s, Object[].class, capacity);
        // 检查是否需要扩容
        ensureCapacityInternal(size);
        
        Object[] a = elementData;
        // 依次读取元素到数组中
        for (int i=0; i

多做比较

在阅读jdk源码的时候,还有很重要的一点,就是要多做比较,比较也可以分为横向比较和纵向比较。

(1)横向比较

就是与相似的类做比较。比如,集合模块中,基本都是各种插入、查询、删除元素,那这时候可以从数据结构、时间复杂度等维度进行比较,这就是横向比较。

(2)纵向比较

可以从集合发展的历史进行比较。比如,HashMap的发展史,从(单个数组)实现(没错,可以直接用一个数组实现HashMap),到(多数组+链表)实现,再到jdk8中的(多数组+链表+红黑树)实现,这就是纵向比较。

多做实验

最后一步,最最最最重要的就是要多做实验。

比如,ConcurrentHashMap是不是强一致性的?

可以启动多个线程去不断调用get()、put()、size()方法,看看是不是强一致性的。

耐心&坚持

这一点我不多说,大家都懂得。

不管是什么领域,耐心&坚持都是最难能可贵的品质。

阅读源码也是一样,只要耐心地坚持下去,终将有所收获。

【推荐课程:Java视频教程

相关专题

更多
java
java

Java是一个通用术语,用于表示Java软件及其组件,包括“Java运行时环境 (JRE)”、“Java虚拟机 (JVM)”以及“插件”。php中文网还为大家带了Java相关下载资源、相关课程以及相关文章等内容,供大家免费下载使用。

832

2023.06.15

java正则表达式语法
java正则表达式语法

java正则表达式语法是一种模式匹配工具,它非常有用,可以在处理文本和字符串时快速地查找、替换、验证和提取特定的模式和数据。本专题提供java正则表达式语法的相关文章、下载和专题,供大家免费下载体验。

738

2023.07.05

java自学难吗
java自学难吗

Java自学并不难。Java语言相对于其他一些编程语言而言,有着较为简洁和易读的语法,本专题为大家提供java自学难吗相关的文章,大家可以免费体验。

734

2023.07.31

java配置jdk环境变量
java配置jdk环境变量

Java是一种广泛使用的高级编程语言,用于开发各种类型的应用程序。为了能够在计算机上正确运行和编译Java代码,需要正确配置Java Development Kit(JDK)环境变量。php中文网给大家带来了相关的教程以及文章,欢迎大家前来阅读学习。

397

2023.08.01

java保留两位小数
java保留两位小数

Java是一种广泛应用于编程领域的高级编程语言。在Java中,保留两位小数是指在进行数值计算或输出时,限制小数部分只有两位有效数字,并将多余的位数进行四舍五入或截取。php中文网给大家带来了相关的教程以及文章,欢迎大家前来阅读学习。

398

2023.08.02

java基本数据类型
java基本数据类型

java基本数据类型有:1、byte;2、short;3、int;4、long;5、float;6、double;7、char;8、boolean。本专题为大家提供java基本数据类型的相关的文章、下载、课程内容,供大家免费下载体验。

446

2023.08.02

java有什么用
java有什么用

java可以开发应用程序、移动应用、Web应用、企业级应用、嵌入式系统等方面。本专题为大家提供java有什么用的相关的文章、下载、课程内容,供大家免费下载体验。

430

2023.08.02

java在线网站
java在线网站

Java在线网站是指提供Java编程学习、实践和交流平台的网络服务。近年来,随着Java语言在软件开发领域的广泛应用,越来越多的人对Java编程感兴趣,并希望能够通过在线网站来学习和提高自己的Java编程技能。php中文网给大家带来了相关的视频、教程以及文章,欢迎大家前来学习阅读和下载。

16925

2023.08.03

Golang gRPC 服务开发与Protobuf实战
Golang gRPC 服务开发与Protobuf实战

本专题系统讲解 Golang 在 gRPC 服务开发中的完整实践,涵盖 Protobuf 定义与代码生成、gRPC 服务端与客户端实现、流式 RPC(Unary/Server/Client/Bidirectional)、错误处理、拦截器、中间件以及与 HTTP/REST 的对接方案。通过实际案例,帮助学习者掌握 使用 Go 构建高性能、强类型、可扩展的 RPC 服务体系,适用于微服务与内部系统通信场景。

8

2026.01.15

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Kotlin 教程
Kotlin 教程

共23课时 | 2.5万人学习

C# 教程
C# 教程

共94课时 | 6.8万人学习

Java 教程
Java 教程

共578课时 | 46.3万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号