這篇文章主要介紹了Java本地快取的實作程式碼,小編覺得挺不錯的,現在分享給大家,也給大家做個參考。一起跟著小編過來看看吧
使用場景
在Java
應用程式中,對於存取頻率高,更新少的數據,通常的方案是將這類資料加入快取中。相對從資料庫讀取來說,讀取快取效率會有很大提升。
在叢集環境下,常用的分散式快取有 Redis 、 Memcached 等。但在某些業務場景上,可能不需要去搭建一套複雜的分散式快取系統,在單機環境下,通常是會希望使用內部的快取( LocalCache )。
實作
這裡提供了兩種 LocalCache
的實現,一種是基於 Con<a href="http://www.php.cn/wiki/1046.html" target="_blank">current</a><a href="http://www.php.cn/wiki/762.html" target="_blank">Hash</a><a href="http://www.php.cn/code/8210.html" target="_blank">Map</a>
實作基本本機緩存,另外一種是基於LinkedHashMap
實作 LRU
策略的本機快取。
基於ConcurrentHashMap的實作
static { timer = new Timer(); map = new ConcurrentHashMap<>(); }
以 ConcurrentHashMap
作為快取的儲存結構。因為 ConcurrentHashMap
的執行緒安全性的,所以基於此實作的 LocalCache
在多執行緒並發環境的操作是安全的。在 JDK1.8
中, ConcurrentHashMap
是支援完全並發讀,這對本機快取的效率也是一種提升。透過呼叫 ConcurrentHashMap
對 map
的操作來實現對快取的操作。
私有建構子
privateLocalCache(){ }
LocalCache
是工具類,透過私有建構函數強化不可實例化的能力。
快取清除機制
/** * 清除缓存任务类 */ static classCleanWorkerTaskextendsTimerTask{ private String key; publicCleanWorkerTask(String key){ this.key = key; } publicvoidrun(){ LocalCache.remove(key); } }
清除失效快取是由 Timer 類別實現的。內部類別 CleanWorkerTask
繼承#於 TimerTask
使用者清除快取。每當新增一個元素的時候,都會呼叫 timer.schedule 載入清除快取的任務。
基於LinkedHashMap的實作
以 LinkedHashMap
作為快取的儲存結構。主要是透過 LinkedHashMap
的按照存取順序的特性來實現 LRU
策略。
LRU
LRU
是 Least Recently Used
的縮寫,即最近最久未使用。 LRU 快取將會利用這個演算法來淘汰快取中舊的資料元素,從而優化記憶體空間。
基於LRU策略的map
這裡利用LinkedHashMap
來實作基於LRU
策略的map
。透過呼叫父類別 LinkedHashMap
的建構子來實例化 map
。參數 accessOrder
設定為 true
保證其可以實現 LRU
策略。
static classLRUMap<K,V>extendsLinkedHashMap<K,V>{ ... // 省略部分代码 publicLRUMap(intinitialCapacity,floatloadFactor){ super(initialCapacity, loadFactor, true); } ... // 省略部分代码 /** * 重写LinkedHashMap中removeEldestEntry方法; * 新增元素的时候,会判断当前map大小是否超过DEFAULT_MAX_CAPACITY,超过则移除map中最老的节点; * * @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
並不是線程安全,如果不加控制的在多執行緒環境下使用的話,會有問題。所以在 LRUMap
中引入了 ReentrantReadWriteLock
讀寫鎖,來控制並發問題。
快取淘汰機制
protectedbooleanremoveEldestEntry(Map.Entry<K, V> eldest){ return size() > DEFAULT_MAX_CAPACITY; }
這裡重寫LinkedHashMap
中removeEldestEntry
方法, 當快取新增元素的時候,會判斷目前map
大小是否超過DEFAULT_MAX_CAPACITY
,超過則移除map中最老的節點。
快取清除機制
快取清除機制與 ConcurrentHashMap
的實作一致,皆透過 timer
實作。
【相關推薦】
1. 特別推薦#:「php程式設計師工具箱」V0.1版本下載
2. Java免費影片教學
3. YMP線上手冊
#以上是java本地快取的程式碼實例的詳細內容。更多資訊請關注PHP中文網其他相關文章!