成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

面試官:如何設計和實現一個帶過期時間的本地緩存?

開發 前端
今天我們來基于ConcurrentHashMap與ScheduledThreadPoolExecutor來實現一個線程安全的本地緩存:LocalCache。在LocalCache中支持永久緩存與臨時緩存,永久緩存的數據一直有效,臨時緩存的數據在指定時間到期之后會自動從緩存中移出。

在日常開發中有很多這樣的場景:有一些業務系統的配置信息,數據量不大,修改頻率不高,但是訪問很頻繁。如果每次程序都從數據庫或集中式緩存中獲取,受限于硬盤 I/O性能、遠程網絡訪問限制等,程序的執行效率不高。在這樣的業務場景中,我們可以通過本地緩存來提升數據訪問的效率。

今天我們來基于ConcurrentHashMap與ScheduledThreadPoolExecutor來實現一個線程安全的本地緩存:LocalCache。在LocalCache中支持永久緩存與臨時緩存,永久緩存的數據一直有效,臨時緩存的數據在指定時間到期之后會自動從緩存中移出。

LocalCache提供了數據安全的增、刪、改、查功能,具體方法如下所示:

方法名稱

方法說明

put(String key , V value)

向緩存中插入數據,數據永久有效

put(String key , V value , int seconds)

向緩存中插入數據,數據根據設定的時間生效,時間到期會從緩存中移出

containKey(String key)

判斷緩存中是否包含對應的key

get(String key)

根據key從緩存中獲取數據

remove(String key)

移出緩存中對應key的數據

shutdownNow()

關閉緩存池

1. 設計原理

LocalCache主要由3個部分組成:數據緩存、數據超時時間、數據清理任務。數據緩存和數據超時時間都采用ConcurrentHashMap來存儲數據,數據超時時間中Key為數據存儲的鍵,value是數據的時間戳。數據清理任務采用ScheduledThreadPoolExecutor實現任務調度,默認的任務線程數為1,這樣可以避免多線程帶來的并發修改問題,同時線程都是內存操作,這樣單線程同樣具備高性能。

本地緩存的設計如下圖所示:

圖片圖片

每次項緩存中插入數據時,LocalCache首先會將數據插入到ConcurrentHashMap中。然后判斷有沒有設置超時時間,如果有超時時間,LocalCache會將失效時間插入到ConcurrentHashMap中,并創建數據清理任務,之后任務提交到ScheduledThreadPoolExecutor線程池中。

每次從緩存中查詢數據,LocalCache會直接從ConcurrentHashMap中讀取數據。

定時任務線程池會按照超時時間來觸發數據清理任務,數據清理任務會從數據時長的緩存池中獲取Key對應的時間,判斷當前Key對應的數據是否已經到期了。如果數據已經到期了,LocalCache會調用remove方法將數據從緩存池中移除。

2. 實現方案

LocalCache作為本地緩存的接口,定義了數據插入、數據刪除、數據查詢的相關接口方法。DefaultLocalCache 定義了兩個ConcurrentHashMap變量:dataMap和timeOutMap。dataMap用來緩存數據信息,timeOutMap用來存儲數據失效的時間戳,同時還定義了數據清理任務ClearTask,ClearTask負責將過期的數據從dataMap中移除。UML圖如下所示:

圖片圖片

3. 代碼展示

3.1 接口定義

public interface LocalCache<V> {
    /**
     * 插入數據,數據永久有效
     */
    boolean put(String key, V value);

    /**
     * 插入數據,在指定時間內生效
     */
    boolean put(String key, V value, int seconds);

    /**
     * 是否包含指定的key
     */
    boolean containKey(String key);

    /**
     * 獲取指定Key的值
     */
    V get(String key);

    /**
     * 從緩存中移除key對應的數據
     */
    void remove(String key);

    void shutdownNow();
}

在接口LocalCache中定義了兩個數據插入的put接口:一個沒有到期時間,另一個有到期時間。沒有到期時間表示數據永久有效,有到期時間的數據會在到期后從緩存中移除。

接口實現

在接口實現DefaultLocalCache內部定義了三個常量:緩存的默認大小DEFAULT_CAPACITY、最大容量MAX_CAPACITY、定時線程池的大小DEFAULT_THREAD_SIZE。核心代碼如下:

public class DefaultLocalCache<V> implements LocalCache<V> {
    // 默認容量
    private static final int DEFAULT_CAPACITY = 1024;
    private static final int MAX_CAPACITY = 100000;

    private static final int DEFAULT_THREAD_SIZE = 1;

    private final int maxSize;

    //數據map
    private volatile ConcurrentHashMap<String,V> dataMap;
    //過期時間
    private final ConcurrentHashMap<String,Long> timeOutMap;

    //定時任務
    private final ScheduledExecutorService executorService;

    public DefaultLocalCache() {
        maxSize = MAX_CAPACITY;
        dataMap = new ConcurrentHashMap<>(DEFAULT_CAPACITY);
        timeOutMap = new ConcurrentHashMap<>(DEFAULT_CAPACITY);
        executorService = new ScheduledThreadPoolExecutor(DEFAULT_THREAD_SIZE) ;
    }

    public DefaultLocalCache(int size) {
        maxSize = size;
        dataMap = new ConcurrentHashMap<>(DEFAULT_CAPACITY);
        timeOutMap = new ConcurrentHashMap<>(DEFAULT_CAPACITY);
        executorService = new ScheduledThreadPoolExecutor(DEFAULT_THREAD_SIZE) ;
    }

    @Override
    public boolean put(String key, V value) {
        //檢查容量
        if(checkCapacity()){
            dataMap.put(key,value);
            return true;
        }
        return false;
    }



    @Override
    public boolean put(String key, V value, int seconds) {
        if(checkCapacity()){
            dataMap.put(key,value);
            if(seconds >= 0){
                timeOutMap.put(key,getTimeOut(seconds));
                ClearTask task = new ClearTask(key);
                executorService.schedule(task, seconds, TimeUnit.SECONDS);
            }
        }
        return false;
    }

 ......

    class ClearTask implements Runnable{
        private String key;

        public ClearTask(String key){
            this.key = key;
        }
        @Override
        public void run() {
            //判斷緩存中是否有key
            if(timeOutMap.contains(key)){
                //獲取失效時間
                Long expire = timeOutMap.get(key);
                //如果失效時間大于0,并且比當前時間小,則刪除緩存
                if(expire > 0){
                    long now = System.currentTimeMillis();
                    if(now >= expire){
                        remove(key);
                    }
                }
            }
        }
    }
}

在LocalCache的默認實現DefaultLocalCache中,基于ConcurrentHashMap與ScheduledThreadPoolExecutor結合使用,使得LocalCache支持永久緩存與臨時緩存兩種能力。

責任編輯:武曉燕 來源: JAVA日知錄
相關推薦

2024-12-26 10:19:16

2024-02-20 14:10:55

系統緩存冗余

2024-01-19 14:03:59

Redis緩存系統Spring

2021-05-19 08:17:35

秒殺場景高并發

2021-12-13 09:02:13

localStorag面試前端

2024-01-15 10:38:20

多級緩存數據一致性分布式緩存

2025-06-04 03:15:00

高并發短鏈系統

2022-08-18 20:02:04

JSLRU緩存

2021-06-09 07:55:19

NodeEventEmitte驅動

2022-04-08 08:26:03

JavaHTTP請求

2021-09-28 13:42:55

Chrome Devwebsocket網絡協議

2024-10-07 08:52:59

分布式系統分布式 IDID

2022-02-07 20:18:29

Redis緩存裝飾

2024-05-28 10:14:31

JavaScrip模板引擎

2025-04-29 02:00:00

高并發系統場景

2023-01-18 17:50:35

系統架構Kafka

2024-09-11 22:51:19

線程通訊Object

2023-11-20 10:09:59

2024-08-07 08:15:47

2015-08-13 10:29:12

面試面試官
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 欧美一级黄色免费 | 黄a在线观看| 精品国产伦一区二区三区观看说明 | 激情亚洲| 精品乱码一区二区三四区视频 | 国产精品欧美一区二区三区 | 日韩中文字幕在线播放 | 亚洲综合国产 | 日韩在线免费视频 | 午夜在线 | 91欧美精品成人综合在线观看 | 一区二区在线免费观看视频 | 一级做a爰片性色毛片视频停止 | 亚洲人在线| 国产成人a亚洲精品 | 涩涩导航| 久久精品久久久久久 | 国产日韩久久 | 亚洲高清一区二区三区 | 少妇av片| 日本电影韩国电影免费观看 | 精品国产乱码久久久久久老虎 | 黄色欧美大片 | 日本精品免费在线观看 | 国产精品一区二区视频 | 国产亚洲成av人片在线观看桃 | 国产一级在线 | 久久婷婷麻豆国产91天堂 | 搞av.com| 欧美日韩亚 | 91精品国产综合久久久久 | 色播视频在线观看 | 日韩伦理电影免费在线观看 | 成人h视频 | 国产高清视频在线观看播放 | 久久国产成人午夜av影院武则天 | 成人性生交大片免费看中文带字幕 | 亚洲www. | 久久99精品久久 | 中文字幕国产视频 | 久久久影院 |