基于ConcurrentHashMap的缓存设计

       使用 ConcurrentHashMap的缓存设计,实现基于本地程序内部的小巧的缓存工具类,具备缓存时效核查,缓存时效删除等功能。设计思路,系统设置两个ConcurrentHashMap变量,一个用来存放我们的value值,一个用来存放vlaue对于的缓存有效时间。系统通过TimerTask定时器,核查是否有过期的key,若过期从缓存中清除。代码如下

package com.zhegui.utils.cache;

import java.util.Map;
import java.util.Set;
import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.ConcurrentHashMap;

/**
 * 基于ConcurrentHashMap的缓存工具类
 *    主要目的: 模拟内存缓存
 * @author Zhegui
 *
 */
public class ConcurrentHashMapCache {


    private ConcurrentHashMapCache(){}

    private static class InnerHolder{
        private static ConcurrentHashMapCache instance = new ConcurrentHashMapCache();
        static{
            CACHE_VALUE = new ConcurrentHashMap<>();
            CACHE_TIME = new ConcurrentHashMap<>();
            cacheTimer();
        }

        /**
         * 设定一个定时器
         */
        private static void cacheTimer(){
            Timer timer = new Timer();
            timer.schedule(new TimerTask() {
                    public void run() {
                        System.out.println("start chedule....");
                        for (String key : CACHE_TIME.keySet()) {
                            Long mapLong = CACHE_TIME.get(key);
                            if(mapLong !=null &&  mapLong < System.currentTimeMillis()){
                                CACHE_VALUE.remove(CACHE_PRX+key);
                                CACHE_TIME.remove(CACHE_PRX+key);
                                System.out.println("remove key:"+key);
                            }
                        }
                    }
            }, 10 * 1000 , 2 * 60 * 1000);
        }
    }

    public static ConcurrentHashMapCache getInstance(){
        return InnerHolder.instance;
    }

    /**
     * 默认缓存key的前缀
     *    
     */
    private static final String CACHE_PRX = "default:";

    /**
     * 默认缓存时间
     */
    private static final long DEFAULT_TIME = 5 * 60 * 1000;

    /**
     * 缓存一分钟
     */
    public static final long ONE_MINUTE = 60 * 1000;


    /**
     * 默认缓存时间 30分钟
     */
    public static final long HALF_HOUR = 30 * 60 * 1000;

    /**
     * 一个小时
     */
    public static final long ONE_HOUR = 60 * 60 * 1000;

    /**
     * 半天
     */
    public static final long HALF_DAY = 12 * 60 * 60 * 1000;

    /**
     * 缓存一个小时
     */
    public static final long ONE_DAY = 2 * HALF_DAY;

    /**
     * 用来缓存真正的值
     */
    private static Map CACHE_VALUE = null; 

    /**
     * 用来缓存时间
     */
    private static Map CACHE_TIME = null;


    /**
     * 默认缓存时间为5分钟
     * @param key
     * @param value
     */
    public void put(String key, String value){
        put(key, value, DEFAULT_TIME);
    }

    /**
     * 存入缓存
     * @param key
     * @param value
     * @param time
     */
    public void put(String key, String value, long time){
        if(key == null || "".equals(key)){
            throw new IllegalArgumentException("key is not allow null or '' ");
        }
        if(time < 0){
            throw new IllegalArgumentException("time must more than 0 '' ");
        }
        CACHE_VALUE.put(CACHE_PRX + key, value);
        CACHE_TIME.put(CACHE_PRX + key, System.currentTimeMillis() + time);
    }

    /**
     * 删除缓存
     * @param key
     */
    public void remove(String key){
        CACHE_VALUE.remove(CACHE_PRX+key);
        CACHE_TIME.remove(CACHE_PRX+key);
    }

    /**
     * 获取缓存的数据
     * @param key
     * @return
     */
    public String get(String key){
        String result = null;
        if(key == null || "".equals(key)){
            return result;
        }
        Long mapLong = CACHE_TIME.get(CACHE_PRX + key);
        if(mapLong != null && mapLong < System.currentTimeMillis()){
            this.remove(key);
        }else{
            result = CACHE_VALUE.get(CACHE_PRX + key);
        }
        return result;
    }

}

编写客户端代码

package com.zhegui.utils.cache;

public class CacheClientTest {
    public static void main(String[] args) throws InterruptedException {
        ConcurrentHashMapCache cache = ConcurrentHashMapCache.getInstance();
        String value = "test3333";
        String key = "key1";
        cache.put(key, value);

        String key2 = "key2";
        String value2 = "value222";
        cache.put(key2, value2, 30 * 1000);

        String key3 = "key3";
        String value3 = "value33333333";
        cache.put(key3, value3, 2 * 60 * 1000);


        Thread.sleep(60 * 1000);

        System.out.println("key1: value = "+cache.get(key));
        System.out.println("key2: value2 = " + cache.get(key2));
        System.out.println("key3: value3 = " + cache.get(key3));
        System.out.println("-------remove key1 --------");
        cache.remove(key);

        System.out.println("key1: value = "+cache.get(key));
        System.out.println("key2: value2 = " + cache.get(key2));
        System.out.println("key3: value3 = " + cache.get(key3));

        Thread.sleep(90 * 1000);
        System.out.println("key3: value3 = " + cache.get(key3));
    }
}

测试结果如下
基于ConcurrentHashMap的缓存设计_第1张图片

总结
       ConcurrentHashMap的并发读写速度很快,而且是线程安全的。为何ConcurrentHashMap速度如此之快,可以参考这里链接内容

你可能感兴趣的:(工具类分享)