1. 程式人生 > >java實現快取框架

java實現快取框架

快取的原理

        外存: 外儲存器是指除計算機記憶體及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"));
    }

}