如何閱讀源碼?
萬事開頭難,源碼從哪里開始看?我也是剛對源碼的閱讀研究不深,但是可以談談自己的源碼閱讀感受。剛開始吧,只是對某些代碼的實現原理感到好奇,好奇是怎么實現這種功能,實現這種效果的,對其背后的原理充滿了求知欲。然后借助 IDEA 以及翻譯插件(本人英語桐油罐子,但這不影響我對原理的探索)一步步查看源碼,調試,但是像無頭蒼蠅一樣不知道哪里是重點,也就很難去理解源碼的思想。
后來源碼看多了,稍微有些經驗了,就知道應該首先了解這項技術的基本原理(可以去百度、看博客),然后通過 IDEA 查看它的繼承關系,有哪些構造方法,都有些什么參數。再然后通過它主要的方法一步步深入了解,只是了解無需做底層的深入研究。當了解它的基本架構后,再針對某一塊代碼深入探索,這樣既能把握整個技術的基本架構,對於深入研究也是很有好處的。
比如 RocketMQ 中間件
比如現在我想了解 RocketMQ 的技術底層,那么首先我得知道它是用來干嘛的,了解一下它的基本架構原理。MQ 嘛,消息中間件,都需要路由、消息服務器這些基本組件。其本質上也是通過腳本啟動的一個 java 進程,那么我就可以通過這個啟動腳本作為入口,去探索 RocketMQ 是如何啟動、提供服務的。
通過研究它的啟動類,發現是讀取了配置,做了一些初始化的操作。像這樣我就知道了 RocketMQ 是如何啟動的,然后再探索它初始化了一些什么東西,比如它有一堆線程池、一些存儲服務、網絡服務。通過這些就能一步步深入了解它實現某些功能的原理,比如說 RocketMQ 的海量存儲原理、支持高並發的原理。按照這種步驟,通過閱讀 RocketMQ 的源碼,一步步的了解其架構原理。
比如線程池
再比如我想了解線程池的技術底層,首先我知道,線程池嘛,里面有很多線程用來處理任務嘛,這就是我對線程池最原始的理解。在我還不會用的時候,我去網上搜索線程池這個技術,發現一大堆的教程啊、遇到什么什么 bug 的解決方法啊、要不就是 jdk 預備的那幾個線程池的描述、使用啊。而把線程池這個東西說清楚的很少,讓人感覺都很有道理,但是對自己好像一點用都沒有。
所以嘛,要講究方法。既然要了解線程池這項技術的原理,首先要知道什么是線程池(現在已經知道啦),然后有哪些線程池(JDK預備的、自定義的),再就是各個線程池有什么區別,然后首先得用起來,比如寫幾個 demo 玩玩。順便淺顯的了解下他們的實現,發現他們都是使用的 ThreadPoolExecutor 實現的,然后自定義也是 ThreadPoolExecutor 實現的,既然如此 ThreadPoolExecutor 就是線程池的重點,那么 ThreadPoolExecutor 就是我學習線程池原理的突破口。
首先使用 IDEA 查看它的繼承關系、構造函數、類屬性等,然后從我使用線程池的時候,使用的 execute 方法作為了解其原理的入口,然后帶着自己的疑問去深入探索。比如線程池這個池子怎么存儲線程的?原來在線程池內部,線程被包裝成了 Worker 對象,然后把 Worker 對象放在 HashSet 集合中,所以線程池實際上就是一個基於 Worker 對象的 Set 集合,然后所有的線程操作都是基於 Worker 對象進行操作的。順着這種思路去了解線程池的原理,比之前無腦亂入要好很多了。