源碼解析:Java本地緩存的實(shí)現(xiàn)代碼

使用場(chǎng)景
在 Java 應(yīng)用中佛掖,對(duì)于訪問頻率高妖碉,更新少的數(shù)據(jù),通常的方案是將這類數(shù)據(jù)加入緩存中芥被。相對(duì)從數(shù)據(jù)庫中讀取來說欧宜,讀緩存效率會(huì)有很大提升。
在集群環(huán)境下拴魄,常用的分布式緩存有 Redis 冗茸、 Memcached 等席镀。但在某些業(yè)務(wù)場(chǎng)景上,可能不需要去搭建一套復(fù)雜的分布式緩存系統(tǒng)夏漱,在單機(jī)環(huán)境下豪诲,通常是會(huì)希望使用內(nèi)部的緩存( LocalCache )。
實(shí)現(xiàn)
這里提供了兩種 LocalCache 的實(shí)現(xiàn)麻蹋,一種是基于 ConcurrentHashMap 實(shí)現(xiàn)基本本地緩存跛溉,另外一種是基于 LinkedHashMap 實(shí)現(xiàn) LRU 策略的本地緩存扮授。
基于ConcurrentHashMap的實(shí)現(xiàn)

static {
  timer = new Timer();
  map = new ConcurrentHashMap<>();
}

以 ConcurrentHashMap 作為緩存的存儲(chǔ)結(jié)構(gòu)。因?yàn)?ConcurrentHashMap 的線程安全的专肪,所以基于此實(shí)現(xiàn)的 LocalCache 在多線程并發(fā)環(huán)境的操作是安全的刹勃。在 JDK1.8 中, ConcurrentHashMap 是支持完全并發(fā)讀嚎尤,這對(duì)本地緩存的效率也是一種提升荔仁。通過調(diào)用 ConcurrentHashMap 對(duì) map 的操作來實(shí)現(xiàn)對(duì)緩存的操作。
私有構(gòu)造函數(shù)

privateLocalCache(){
 
}
LocalCache 是工具類芽死,通過私有構(gòu)造函數(shù)強(qiáng)化不可實(shí)例化的能力乏梁。
緩存清除機(jī)制
/**
 * 清除緩存任務(wù)類
 */
 static classCleanWorkerTaskextendsTimerTask{
 
   private String key;
 
   publicCleanWorkerTask(String key){
     this.key = key;
   }
 
   publicvoidrun(){
     LocalCache.remove(key);
   }
 }

清理失效緩存是由 Timer 類實(shí)現(xiàn)的。內(nèi)部類 CleanWorkerTask 繼承于 TimerTask 用戶清除緩存关贵。每當(dāng)新增一個(gè)元素的時(shí)候遇骑,都會(huì)調(diào)用 timer.schedule 加載清除緩存的任務(wù)。
基于LinkedHashMap的實(shí)現(xiàn)
以 LinkedHashMap 作為緩存的存儲(chǔ)結(jié)構(gòu)揖曾。主要是通過 LinkedHashMap 的按照訪問順序的特性來實(shí)現(xiàn) LRU 策略落萎。
LRU
LRU 是 Least Recently Used 的縮寫,即最近最久未使用炭剪。 LRU 緩存將會(huì)利用這個(gè)算法來淘汰緩存中老的數(shù)據(jù)元素练链,從而優(yōu)化內(nèi)存空間。
基于LRU策略的map
這里利用 LinkedHashMap 來實(shí)現(xiàn)基于 LRU 策略的 map 奴拦。通過調(diào)用父類 LinkedHashMap 的構(gòu)造函數(shù)來實(shí)例化 map 媒鼓。參數(shù) accessOrder 設(shè)置為 true 保證其可以實(shí)現(xiàn) LRU 策略。

static classLRUMap<K,V>extendsLinkedHashMap<K,V>{
 
    ... // 省略部分代碼
     
    publicLRUMap(intinitialCapacity,floatloadFactor){
      super(initialCapacity, loadFactor, true);
    }
 
    ... // 省略部分代碼
     
    /**
     * 重寫LinkedHashMap中removeEldestEntry方法;
     * 新增元素的時(shí)候,會(huì)判斷當(dāng)前map大小是否超過DEFAULT_MAX_CAPACITY,超過則移除map中最老的節(jié)點(diǎn);
     *
     * @param eldest
     * @return
     */
    protectedbooleanremoveEldestEntry(Map.Entry<K, V> eldest){
      return size() > DEFAULT_MAX_CAPACITY;
    }
 
  }

線程安全

/**
 * 讀寫鎖
 */
private final ReadWriteLock readWriteLock = new ReentrantReadWriteLock();
 
private final Lock rLock = readWriteLock.readLock();
 
private final Lock wLock = readWriteLock.writeLock();

LinkedHashMap 并不是線程安全错妖,如果不加控制的在多線程環(huán)境下使用的話隶糕,會(huì)有問題。所以在 LRUMap 中引入了 ReentrantReadWriteLock 讀寫鎖站玄,來控制并發(fā)問題枚驻。
緩存淘汰機(jī)制

protectedbooleanremoveEldestEntry(Map.Entry<K, V> eldest){
  return size() > DEFAULT_MAX_CAPACITY;
}

此處重寫 LinkedHashMap 中 removeEldestEntry 方法, 當(dāng)緩存新增元素的時(shí)候,會(huì)判斷當(dāng)前 map 大小是否超過 DEFAULT_MAX_CAPACITY ,超過則移除map中最老的節(jié)點(diǎn)株旷。
緩存清除機(jī)制
緩存清除機(jī)制與 ConcurrentHashMap 的實(shí)現(xiàn)一致再登,均是通過 timer 實(shí)現(xiàn)尔邓。
推薦大家閱讀:
Java高級(jí)架構(gòu)學(xué)習(xí)資料分享+架構(gòu)師成長(zhǎng)之路?
個(gè)人整理了更多資料以PDF文件的形式分享給大家,需要查閱的程序員朋友可以來免費(fèi)領(lǐng)取锉矢。還有我的學(xué)習(xí)筆記PDF文件也免費(fèi)分享給有需要朋友梯嗽!
順便給大家推薦一個(gè)Java技術(shù)交流群:473984645里面會(huì)分享一些資深架構(gòu)師錄制的視頻資料:有Spring,MyBatis沽损,Netty源碼分析灯节,高并發(fā)、高性能绵估、分布式炎疆、微服務(wù)架構(gòu)的原理,JVM性能優(yōu)化国裳、分布式架構(gòu)等這些成為架構(gòu)師必備的知識(shí)體系形入。還能領(lǐng)取免費(fèi)的學(xué)習(xí)資源,目前受益良多缝左!

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末亿遂,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子渺杉,更是在濱河造成了極大的恐慌蛇数,老刑警劉巖,帶你破解...
    沈念sama閱讀 219,539評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件是越,死亡現(xiàn)場(chǎng)離奇詭異耳舅,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)英妓,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,594評(píng)論 3 396
  • 文/潘曉璐 我一進(jìn)店門挽放,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人蔓纠,你說我怎么就攤上這事辑畦。” “怎么了腿倚?”我有些...
    開封第一講書人閱讀 165,871評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵纯出,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我敷燎,道長(zhǎng)暂筝,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,963評(píng)論 1 295
  • 正文 為了忘掉前任硬贯,我火速辦了婚禮焕襟,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘饭豹。我一直安慰自己鸵赖,他們只是感情好务漩,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,984評(píng)論 6 393
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著它褪,像睡著了一般饵骨。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上茫打,一...
    開封第一講書人閱讀 51,763評(píng)論 1 307
  • 那天居触,我揣著相機(jī)與錄音,去河邊找鬼老赤。 笑死轮洋,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的诗越。 我是一名探鬼主播砖瞧,決...
    沈念sama閱讀 40,468評(píng)論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼息堂,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼嚷狞!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起荣堰,我...
    開封第一講書人閱讀 39,357評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤床未,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后振坚,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體薇搁,經(jīng)...
    沈念sama閱讀 45,850評(píng)論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,002評(píng)論 3 338
  • 正文 我和宋清朗相戀三年渡八,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了啃洋。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,144評(píng)論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡屎鳍,死狀恐怖宏娄,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情逮壁,我是刑警寧澤孵坚,帶...
    沈念sama閱讀 35,823評(píng)論 5 346
  • 正文 年R本政府宣布,位于F島的核電站窥淆,受9級(jí)特大地震影響卖宠,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜忧饭,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,483評(píng)論 3 331
  • 文/蒙蒙 一扛伍、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧词裤,春花似錦刺洒、人聲如沸汁咏。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,026評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽攘滩。三九已至,卻和暖如春纸泡,著一層夾襖步出監(jiān)牢的瞬間漂问,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,150評(píng)論 1 272
  • 我被黑心中介騙來泰國(guó)打工女揭, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留蚤假,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,415評(píng)論 3 373
  • 正文 我出身青樓吧兔,卻偏偏與公主長(zhǎng)得像磷仰,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子境蔼,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,092評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容

  • 源碼地址: GitHub 使用場(chǎng)景 在Java應(yīng)用中灶平,對(duì)于訪問頻率高,更新少的數(shù)據(jù)箍土,通常的方案是將這類數(shù)據(jù)加入緩存...
    特立獨(dú)行的豬手閱讀 20,265評(píng)論 0 18
  • Java SE 基礎(chǔ): 封裝逢享、繼承、多態(tài) 封裝: 概念:就是把對(duì)象的屬性和操作(或服務(wù))結(jié)合為一個(gè)獨(dú)立的整體吴藻,并盡...
    Jayden_Cao閱讀 2,110評(píng)論 0 8
  • 不足的地方請(qǐng)大家多多指正瞒爬,如有其它沒有想到的常問面試題請(qǐng)大家多多評(píng)論,一起成長(zhǎng)沟堡,感謝!~ String可以被繼承嗎...
    啟示錄是真的閱讀 2,940評(píng)論 3 3
  • 學(xué)習(xí)java并發(fā)的時(shí)候航罗,書上的例子是基于緩存展開的禀横,于是就想可以寫一個(gè)通用的本地緩存 寫在前面 寫一個(gè)緩存,需要考...
    何甜甜在嗎閱讀 214評(píng)論 0 0
  • 所到幣圈之處伤哺,到家都說一個(gè)詞ico,今天就科普一下燕侠,什么事icoIco是一種區(qū)塊鏈行業(yè)術(shù)語,是initial. C...
    40歲重生閱讀 705評(píng)論 0 0