java實現快取框架
阿新 • • 發佈:2019-01-05
快取的原理
外存: 外儲存器是指除計算機記憶體及CPU快取以外的儲存器,此類儲存器一般斷電後仍然能儲存資料。常見的外儲存器有硬碟、軟盤、光碟、U盤等,一般的軟體都是安裝在外存中(windows系統指的是CDEF盤, Linux系統指的是掛載點)。
記憶體:記憶體是計算機中重要的部件之一,它是與CPU進行溝通的橋樑。計算機中所有程式的執行都是在記憶體中進行的,因此記憶體的效能對計算機的影響非常大。記憶體(Memory)也被稱為記憶體儲器,其作用是用於暫時存放CPU中的運算資料,以及與硬碟等外部儲存器交換的資料。只要計算機在執行中,CPU就會把需要運算的資料調到記憶體中進行運算,當運算完成後CPU再將結果傳送出來,記憶體的執行也決定了計算機的穩定執行, 此類儲存器一般斷電後資料就會被清空。
快取:快取是用來協調CPU與主存之間存取速度的差異而設定的。一般情況下,CPU的工作速度高,但記憶體的工作速度相對較低,為了解決這個問題,通常使用快取記憶體,快取記憶體的存取速度介於CPU和主存之間。系統將一些CPU在近幾個時間段經常訪問的內容存入高速緩衝,當CPU需要使用資料時,先在快取記憶體中找,如果找到,就不必訪問記憶體了,找不到時,再找記憶體,這樣就在一定程度上緩解了由於主存速度低造成的CPU“停工待料”的情況。
快取就是把一些外存上的資料儲存到記憶體上而已,怎麼儲存到記憶體上呢,我們執行的所有程式,裡面的變數值都是放在記憶體上的,所以說如果要想使一個值放到記憶體上,實質就是在獲得這個變數之後,用一個生存期較長的變數存放你想存放的值,在java中一些快取一般都是通過map集合來做的。
簡單講就是,如果某些資源或者資料會被頻繁的使用,而這些資源或資料儲存在系統外部,比如資料庫、硬碟檔案等,那麼每次操作這些資料的時候都從資料庫或者硬碟上去獲取,速度會很慢,會造成效能問題。一個簡單的解決方法就是:把這些資料快取到記憶體裡面,每次操作的時候,先到記憶體裡面找,看有沒有這些資料,如果有,那麼就直接使用,如果沒有那麼就獲取它,並設定到快取中,下一次訪問的時候就可以直接從記憶體中獲取了。從而節省大量的時間,當然,快取是一種典型的空間換時間的方案。
基本概念講的差不多了, 現在用java來實現一個基本的快取框架:
思路:
1. 先得有一個快取實體類
2. 考慮用map作為儲存容器
3. 設定快取有效時間, 當時間失效時, 清除快取資料
4. 用執行緒的方式實現簡單的快取框架
程式碼實現:
package com.cache.demo;
/**
* @Description 快取實體類
* @author ShengLiu
* @date 2018/7/8
*/
public class Cache {
public Cache(){
}
public Cache(String key, Object value, Long timeOut){
super();
this.key = key;
this.value = value;
this.timeOut = timeOut;
}
/**
* key
*/
private String key;
/**
* 快取資料
*/
private Object value;
/**
* 超時時間
*/
private Long timeOut;
public String getKey() {
return key;
}
public void setKey(String key) {
this.key = key;
}
public Object getValue() {
return value;
}
public void setValue(Object value) {
this.value = value;
}
public Long getTimeOut() {
return timeOut;
}
public void setTimeOut(Long timeOut) {
this.timeOut = timeOut;
}
@Override
public String toString() {
return "Cache{" +
"key='" + key + '\'' +
", value=" + value +
", timeOut=" + timeOut +
'}';
}
}
package com.cache.demo;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
/**
* @Description 快取map
* @author ShengLiu
* @date 2018/7/8
*/
public class CacheManager {
/**
* 存放快取資料
*/
private Map<String, Object> cacheMap = new HashMap<>();
/**
* @Description 往快取中存資料
* @author ShengLiu
* @date 2018/7/8
* @param key
* @param value
* @return void
*/
public synchronized void put(String key, Object value){
put(key, value, null);
}
/**
* @Description 往快取中存資料
* @author ShengLiu
* @date 2018/7/8
* @param key
* @param value
* @param timeout
* @return void
*/
public synchronized void put(String key, Object value, Long timeout){
if (value == null){
return;
}
Cache cache = new Cache();
cache.setKey(key);
cache.setValue(value);
if (timeout != null){
cache.setTimeOut(timeout + System.currentTimeMillis());
}
cache.setValue(value);
cacheMap.put(key, cache);
}
/**
* @Description 刪除
* @author ShengLiu
* @date 2018/7/8
* @param key
* @return void
*/
public synchronized void deleteCache(String key){
cacheMap.remove(key);
}
/**
* @Description 獲取快取中的資料
* @author ShengLiu
* @date 2018/7/8
* @param key
* @return java.lang.Object
*/
public synchronized Object get(String key){
Cache cache = (Cache) cacheMap.get(key);
Object obj = null;
if (cache != null){
obj = cache.getValue();
}
return obj;
}
/**
* @Description 檢查資料是否在有效期內
* @author ShengLiu
* @date 2018/7/8
* @param
* @return void
*/
public synchronized void checkValidityData(){
for (String key: cacheMap.keySet()){
Cache cache = (Cache) cacheMap.get(key);
Long timeOut = cache.getTimeOut();
if(timeOut == null){
return;
}
long currentTime = System.currentTimeMillis();
long endTime = timeOut;
long resultTime = (currentTime - endTime);
if (resultTime > 0){
System.out.println("清除: " + key);
cacheMap.remove(key);
}
}
}
public static void main(String[] args) throws InterruptedException {
final CacheManager cacheManager = new CacheManager();
cacheManager.put("jj", "林俊杰", 5000L);
ScheduledExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(5);
scheduledThreadPool.schedule(new Runnable() {
@Override
public void run() {
cacheManager.checkValidityData();
}
}, 5000, TimeUnit.MILLISECONDS);
Thread.sleep(5000);
System.out.println("儲存成功");
System.out.println(cacheManager.get("jj"));
}
}