天天看點

【源代碼】LruCache源代碼剖析

上一篇分析了LinkedHashMap源代碼,這個Map集合除了擁有HashMap的大部分特性之外。還擁有連結清單的特點,即能夠保持周遊順序與插入順序一緻。

另外。當我們将accessOrder設定為true時。能夠使周遊順序和訪問順序一緻,其内部雙向連結清單将會依照最近最少訪問到最近最多訪問的順序排列Entry對象,這能夠用來做緩存。

這篇文章分析的LruCache并非jdk中的類,而是來自安卓,熟悉安卓記憶體緩存的必定對這個類不陌生。

LruCache内部維護的就是一個LinkedHashMap。

以下開始分析LruCache。

注:以下LruCache源代碼來自support.v4包。

首先是這個類的成員變量:

LinkedHashMap的初始化放在構造器中:

這裡将LinkedHashMap的accessOrder設定為true。

接下來看兩個最重要的方法,put和get。

首先是put方法:

put方法無非就是調用LinkedHashMap的put方法。可是這裡在調用LinkedHashMap的put方法之前,推斷了key和value是否為空,也就是說LruCache不同意空鍵值。

除此之外,put操作被加鎖了,是以是線程安全的!

既然是緩存,那麼必定可以動态删除一些不經常使用的鍵值對,這個工作是由trimToSize方法完畢的:

這種方法不斷循環删除連結清單首部元素。也就是近期最少訪問的元素,直到容量不超過預先定義的最大值為止。

注:LruCache在android.util包中也有一個LruCache類,可是我發現這個類的trimToSize方法是錯誤的:

這裡的代碼将會循環删除連結清單尾部,也就是近期訪問最多的元素,這是不對的!是以大家在做記憶體緩存的時候一定要注意,看trimToSize方法是否有問題。

接下來是get方法:

get方法即依據key在LinkedHashMap中尋找相應的value,此方法也是線程安全的。

以上就是LruCache最重要的部分,以下再看下其它方法:

remove:

sizeof:這種方法用于計算每一個條目的大小,子類必須得複寫這個類。

snapshot方法,傳回目前緩存中全部的條目集合

總結:

1.LruCache封裝了LinkedHashMap。提供了LRU緩存的功能;

2.LruCache通過trimToSize方法自己主動删除近期最少訪問的鍵值對。

3.LruCache不同意空鍵值;

4.LruCache線程安全。

5.繼承LruCache時,必需要複寫sizeof方法。用于計算每一個條目的大小。

繼續閱讀