基于ConcurrentHashMap封装的缓存工具类

import com.weds.framework.core.exception.ErrorCodeException;
import lombok.Data;
import lombok.SneakyThrows;
import org.apache.commons.lang3.ObjectUtils;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantReadWriteLock;

/**
 * @description: <br/>
 * 基于ConcurrentHashMap封装的缓存工具类
 * <p>
 * <br/>
 * @author: Qz1997
 * @create 2021/7/9 11:00
 */
@SuppressWarnings("unused")
public class MapCacheManager {

    /**
     * 私有构造单例模式
     */
    private MapCacheManager() {
    }

    /**
     * 是否开启清除失效缓存
     */
    private volatile Boolean clearExpireCacheEnable = true;
    /**
     * 缓存失效时间 30分钟
     */
    private long cacheTimeout = 30 * 60 * 1000L;

    /**
     * 可缓存最大数量
     */
    private Integer maxCacheSize = 200;

    /**
     * 重入读写锁
     */
    private static ReentrantReadWriteLock reentrantReadWriteLock = new ReentrantReadWriteLock();
    /**
     * 读锁
     */
    private static Lock writeLock = reentrantReadWriteLock.writeLock();
    /**
     * 写锁
     */
    private static Lock readLock = reentrantReadWriteLock.readLock();

    /**
     * 存储对象的ConcurrentHashMap
     */
    private final static Map<String, CacheEntry> CACHE_ENTRY_MAP = new ConcurrentHashMap<>();

    /**
     * 初始化
     */
    public void init() {
        initClearTask();
    }

    /**
     * 初始化 自定义缓存失效时间
     *
     * @param cacheTimes 缓存失效时间
     */
    public void init(long cacheTimes) {
        this.cacheTimeout = cacheTimes;
        initClearTask();
    }

    /**
     * 初始化 自定义缓存失效时间
     *
     * @param cacheTimes   缓存失效时间
     * @param maxCacheSize 最大缓存数
     */
    public void init(long cacheTimes, int maxCacheSize) {
        this.cacheTimeout = cacheTimes;
        this.maxCacheSize = maxCacheSize;
        initClearTask();
    }

    /**
     * 清除缓存线程
     */
    private void initClearTask() {
        //启动清除失效缓存数据
        if (clearExpireCacheEnable) {
            new ClearCacheTask().start();
        }
    }

    /**
     * 获取缓存管理器
     *
     * @return 缓存管理器
     */
    public static MapCacheManager getCacheManagerInstance() {
        return CacheManagerFactory.CACHE_MANAGER;
    }

    /**
     * 获取缓存管理器工厂
     *
     * @author Qz1997
     */
    private static class CacheManagerFactory {
        private static final MapCacheManager CACHE_MANAGER = new MapCacheManager();
    }

    /**
     * 清除缓存工具
     *
     * @author Qz1997
     */
    private class ClearCacheTask extends Thread {
        ClearCacheTask() {
            super.setName("清除缓存线程");
        }

        @Override
        @SneakyThrows
        public void run() {
            while (clearExpireCacheEnable) {
                CACHE_ENTRY_MAP.keySet().forEach(key -> {
                    writeLock.lock();
                    try {
                        CacheEntry entry = CACHE_ENTRY_MAP.get(key);
                        long now = System.currentTimeMillis();
                        if (ObjectUtils.isNotEmpty(entry) && entry.lastTouchTime < now) {
                            CACHE_ENTRY_MAP.remove(key);
                        }
                    } finally {
                        writeLock.unlock();
                    }
                });
                Thread.sleep(1000);
            }
        }
    }

    /**
     * 缓存对象
     *
     * @author Qz1997
     */
    @Data
    private static class CacheEntry {
        long lastTouchTime;
        Object value;

        CacheEntry(Object value, long lastTouchTime) {
            super();
            this.value = value;
            this.lastTouchTime = lastTouchTime + System.currentTimeMillis();
        }
    }

    /**
     * 获取缓存的value
     *
     * @param key 缓存Key
     * @return value
     */
    public Object get(String key) {
        CacheEntry entry;
        readLock.lock();
        try {
            entry = CACHE_ENTRY_MAP.get(key);
        } finally {
            readLock.unlock();
        }
        if (null == entry) {
            return null;
        }
        return entry.value;
    }


    /**
     * 获取缓存的value
     *
     * @param key 缓存Key
     * @return value
     */
    @SuppressWarnings("unchecked")
    public <T> T get(String key, Class<T> clazz) {
        if (ObjectUtils.isEmpty(clazz)) {
            return null;
        }
        CacheEntry entry;
        readLock.lock();
        try {
            entry = CACHE_ENTRY_MAP.get(key);
        } finally {
            readLock.unlock();
        }
        if (null == entry) {
            return null;
        }
        return (T) entry.value;
    }

    /**
     * 向缓存中加值
     *
     * @param key   缓存中的Key
     * @param value 缓存中的value
     */
    public void put(String key, Object value) {
        put(key, value, 0);
    }

    /**
     * 向缓存中加值
     *
     * @param key           缓存中的Key
     * @param value         缓存中的value
     * @param lastTouchTime 缓存过期时间
     */
    public void put(String key, Object value, long lastTouchTime) {
        if (CACHE_ENTRY_MAP.size() > maxCacheSize) {
            throw new ErrorCodeException("缓存大小超出限制");
        }
        // 过期时间
        lastTouchTime = lastTouchTime <= 0 ? cacheTimeout : (lastTouchTime * 1000);
        CacheEntry entry = new CacheEntry(value, lastTouchTime);
        writeLock.lock();
        try {
            CACHE_ENTRY_MAP.put(key, entry);
        } finally {
            writeLock.unlock();
        }
    }

    /**
     * 删除
     *
     * @param key 缓存中的Key
     */
    public void delete(String key) {
        if (null == key) {
            return;
        }
        writeLock.lock();
        try {
            CACHE_ENTRY_MAP.remove(key);
        } finally {
            writeLock.unlock();
        }
    }

    /**
     * 情况缓存
     */
    public void clear() {
        writeLock.lock();
        try {
            CACHE_ENTRY_MAP.clear();
        } finally {
            writeLock.unlock();
        }
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值