缘起
继续从读书笔记的角度来系统的学习《Advanced Design and Implementation of Virtual Machines》。今天介绍第六章“Design of Threading”。这本书是英文编写,全部、认真、深入的读下来非常考验人。我之前也只是读了60%,而且越到后面越没有耐心。想了想,JVM在系统层面上要达到一定水准,可能还是得精读一到两本这样的书籍。记读书笔记是我学习知识和技能的一种比较好的方式,伴随我至少20多年了。暂且给这次的读书笔记取名“关于VM的理论”。
这一章到底在讲什么?
今天要介绍的是原书第六章,标题是“Design of Threading”,大概是介绍VM中的多线程相关的知识。但不知道为什么,这一章节我个人感觉(大胆推测大部分读者也有同感)比较枯燥——说白了有些不知所云。很可能是多线程这个东西大家都相对熟悉,在这一章节里又不能谈太多后面的内容,所以显得鸡肋。基于这个考虑。我们这节读书笔记也相对简单。
编程语言支持线程的两种方式
先看本章开篇就毫不起眼却力透纸背的一个重要常识:
语言支持线程的两种方式是开篇第一句话 ,如果不注意的话真的会忽视(这也是我坚持阅读英文原版的目的,因为会强迫我读的慢)。我
从来没想过这个问题....。比如,
C语言就没有对线程的支持,需要依赖windowsAPI或linux上的POSIX。
而C++也是到11(不确定是否准确)才在 语言层面上支持线程(通过 std thread 库) ....
但 android 里的 C++ 貌似没有这个。
关于C++11在语言层面对多线程的支持,可参考我在写《深入理解Android Java虚拟机ART》一书时翻过的《C++ Concurrency in Action》,保证看到想哭.....
到底什么是线程
作者花了大篇幅来讲线程是什么。这一点感觉让人佩服的同时又有些崩溃。一本讲JVM高级设计实现的书还要花这么多笔墨介绍线程是什么?
Anyway,看看作者要说些什么....
上图中,线程被高度抽象为一个执行流(Control Flow),这个执行流有两个关键标示, 一个是PC , 一个是栈顶指针SP 。这两个关键标示一个用于控制指令,一个控制数据存储。所以,一个最简化的所谓的线程上下文( Thread Context )就包含这两个信息就行了。而实际上呢,在真实系统上,Thread Context往往还会包含那个线程使用的寄存器的信息。BTW,这个定义的线程是和当前主流计算机结构有关(即冯诺依曼结构)。我在另外几本关于函数式编程发源、演化历史的书里了解到,曾经出现过一些更符合函数式编程的计算机体系结构......这些内容,我后续也想通过读书笔记方式给大家讲讲。
那么,计算机从硬件、到OS、到VM再到APP是如何实现线程的呢?请看下面这个图:
这个图涉及到很多知识,如果你发现阅读困难的话,建议读我很早前写的一篇文章( 关于线程和I/O模型的极简知识 )。在这篇文章里,你会了解更多基础性知识。建议你仔细阅读。
ART中的线程表示
ART中(我猜测现代大部分JVM也是这样),
一个Java线程对应一个OS线程。
ART代码中,Thread类是线程的代表。其中有展示线程状态的变量。
Thread类还包含一个代表Thread Context的结构体(tlsPtr_ )。
最后,ART中,Java线程真正的入口(从Pthread线程这个层次来看)函数是Thread::CreateCallback。
Mutex和CV的基础知识
多线程知识除了线程外,同步相关的知识是其中的基础核心部分。一般而言,多线程同步涉及两个概念,一个是Mutex,一个是Conditional Variable。
关于Mutex和CV的人性化描述如下:
Mutex:只有一个厕所,五个人要上。谁先进去的话,其他4个人等着。先进去的人号称抢到了锁(或者Mutex)。在Windows编程里,叫Critial Section。
CV:其他4个人在外面等着上厕所。两种等法,一种是轮询去看厕所门开了没有。另外一种是厕所里的人出来后,点亮一个通知灯。其余的人只要看到灯亮了就知道可以去抢位了。
特别要指出的是 ,CV和Mutex并不是两种等价的线程同步手段,它们是分别用来解决不同问题的。而且,CV往往要配合Mutex使用。
JVM中的Mutex和CV
上图介绍了JVM中Mutex和CV的实现情况。
Java在语言层面通过synchronized关键字直接就支持了Mutex。而JVM内部则是通过monitorenter/monitorexit两个指令来实现Mutex的处理
而CV则是通过Object的Wait和Notify函数支持。
ART虚拟机中,Mutex和CV的入口代码都在Object中。如上图右下角所示。更进一步的知识,请看下图提示。
所以,提示就是,关于ART里monitor、wait、notify的处理,可阅读我书的第12章12.3节。
喔对了,书中接下来介绍了Atomic,居然还不是volatile...Atomic是Java中的AtomicXXX类,我觉得没有什么特别好说的...
最后,作者介绍了JVM中的线程。按线程的功能来分,大概就是Mutator、Collector、JIT编译线程、处理finalization和weak-referencing的线程。然后又用了不少篇幅介绍线程Suspension和GC的交互。单看这些内容确实有点莫名其妙.....我觉得不如先放放,等后面在GC的场景里再来介绍会更水到渠成一点。
终于,到此我们介绍了全书的第一部分和第二部分。整个书分为五个部分,第一部分是“Basics of VM”,第二部分是“Design of VM”。第三部分内容如下,章节最多(七章)。再后面两个部分就是高级篇。所以,第三部分内容应该是最难也最少被人了解的。BTW,面试喜欢虐人的看来有料了....
看来这本书还得花不少时间好好读.....
后续的安排
我想重点树立起和JVM密切有关的知识体系。有了ART源码打底子,我相信这条路走得通。对JVM的掌握是非常有必要的,我感觉国家层面在底层基础核心技术上会加大投入,JVM是一个非常合适的突破口。
最后的最后
我期望的结果不是朋友们从我的书、文章、博客后学会了什么知识,干成了什么,而应该是说, 神农,我可是踩在你的肩膀上的喔 。
关于学习方面的问题,我已经讨论完了。 后面这个公众号将对一些基础的技术,新技术做一些学习和分享。也欢迎你的投稿 。不过,正如我在公众号“联系方式”里说的那样——郑渊洁在童话大王《智齿》里有一句话令我印象深刻,大意是“我有权保持沉默,但你说的每一句话都可能成为我灵感的源泉”。 所以,影响不是单向的,很可能我从你那学到的东西更多 。
神农和朋友们的杂文集
长按识别二维码关注我们