Java本地緩存的實現(xiàn)代碼
使用場景
在 Java 應用中,對于訪問頻率高,更新少的數(shù)據(jù),通常的方案是將這類數(shù)據(jù)加入緩存中。相對從數(shù)據(jù)庫中讀取來說,讀緩存效率會有很大提升。
在集群環(huán)境下,常用的分布式緩存有 Redis 、 Memcached 等。但在某些業(yè)務場景上,可能不需要去搭建一套復雜的分布式緩存系統(tǒng),在單機環(huán)境下,通常是會希望使用內部的緩存( LocalCache )。
實現(xiàn)
這里提供了兩種 LocalCache 的實現(xiàn),一種是基于 ConcurrentHashMap 實現(xiàn)基本本地緩存,另外一種是基于 LinkedHashMap 實現(xiàn) LRU 策略的本地緩存。
基于ConcurrentHashMap的實現(xiàn)
static {
timer = new Timer();
map = new ConcurrentHashMap<>();
}
以 ConcurrentHashMap 作為緩存的存儲結構。因為 ConcurrentHashMap 的線程安全的,所以基于此實現(xiàn)的 LocalCache 在多線程并發(fā)環(huán)境的操作是安全的。在 JDK1.8 中, ConcurrentHashMap 是支持完全并發(fā)讀,這對本地緩存的效率也是一種提升。通過調用 ConcurrentHashMap 對 map 的操作來實現(xiàn)對緩存的操作。
私有構造函數(shù)
privateLocalCache(){
}
LocalCache 是工具類,通過私有構造函數(shù)強化不可實例化的能力。
緩存清除機制
/**
* 清除緩存任務類
*/
static classCleanWorkerTaskextendsTimerTask{
private String key;
publicCleanWorkerTask(String key){
this.key = key;
}
publicvoidrun(){
LocalCache.remove(key);
}
}
清理失效緩存是由 Timer 類實現(xiàn)的。內部類 CleanWorkerTask 繼承于 TimerTask 用戶清除緩存。每當新增一個元素的時候,都會調用 timer.schedule 加載清除緩存的任務。
基于LinkedHashMap的實現(xiàn)
以 LinkedHashMap 作為緩存的存儲結構。主要是通過 LinkedHashMap 的按照訪問順序的特性來實現(xiàn) LRU 策略。
LRU
LRU 是 Least Recently Used 的縮寫,即最近最久未使用。 LRU 緩存將會利用這個算法來淘汰緩存中老的數(shù)據(jù)元素,從而優(yōu)化內存空間。
基于LRU策略的map
這里利用 LinkedHashMap 來實現(xiàn)基于 LRU 策略的 map 。通過調用父類 LinkedHashMap 的構造函數(shù)來實例化 map 。參數(shù) accessOrder 設置為 true 保證其可以實現(xiàn) LRU 策略。
static classLRUMap<K,V>extendsLinkedHashMap<K,V>{
... // 省略部分代碼
publicLRUMap(intinitialCapacity,floatloadFactor){
super(initialCapacity, loadFactor, true);
}
... // 省略部分代碼
/**
* 重寫LinkedHashMap中removeEldestEntry方法;
* 新增元素的時候,會判斷當前map大小是否超過DEFAULT_MAX_CAPACITY,超過則移除map中最老的節(jié)點;
*
* @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)境下使用的話,會有問題。所以在 LRUMap 中引入了 ReentrantReadWriteLock 讀寫鎖,來控制并發(fā)問題。
緩存淘汰機制
protectedbooleanremoveEldestEntry(Map.Entry<K, V> eldest){
return size() > DEFAULT_MAX_CAPACITY;
}
此處重寫 LinkedHashMap 中 removeEldestEntry 方法, 當緩存新增元素的時候,會判斷當前 map 大小是否超過 DEFAULT_MAX_CAPACITY ,超過則移除map中最老的節(jié)點。
緩存清除機制
緩存清除機制與 ConcurrentHashMap 的實現(xiàn)一致,均是通過 timer 實現(xiàn)。
源碼地址: GitHub
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。
相關文章
Java?實戰(zhàn)項目之家政服務平臺系統(tǒng)的實現(xiàn)流程
讀萬卷書不如行萬里路,只學書上的理論是遠遠不夠的,只有在實戰(zhàn)中才能獲得能力的提升,本篇文章手把手帶你用java+SSM+jsp+mysql+maven實現(xiàn)家政服務平臺系統(tǒng),大家可以在過程中查缺補漏,提升水平2021-11-11
SpringBoot2.x配置多數(shù)據(jù)源方式
這篇文章主要介紹了SpringBoot2.x配置多數(shù)據(jù)源方式,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2024-03-03
IDEA使用properties配置文件進行mysql數(shù)據(jù)庫連接的教程圖解
Properties類是 鍵和值均為字符串的可以永久存儲到文件中的key-value集合。這篇文章主要介紹了IDEA使用properties配置文件進行mysql數(shù)據(jù)路連接 ,需要的朋友可以參考下2018-10-10
JAVA?biginteger類bigdecimal類的使用示例學習
這篇文章主要為大家介紹了JAVA?biginteger類bigdecimal類的使用示例學習,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2022-07-07

