search.png
关于我
menu.png
java 基于Map实现的简单又实用的缓存组件

收录于墨的2020~2021开发经验总结

这个是我使用 Java 内置的 MAP 实现的简易缓存,适用于一些轻量级缓存,现在公开出来,希望能帮助到大家:


import lombok.extern.slf4j.Slf4j;
import org.springframework.data.util.Pair;

import java.util.HashSet;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.TimeUnit;

/**
 * 使用 Java 内置的 MAP 实现的简易缓存,适用于一些轻量级缓存
 *
 * @author hengyumo
 * @since 2021-06-06
 */
@Slf4j
public class DawnSimpleCache {

    /**
     * 保存缓存数据
     */
    private final Map<String, Object> cache;

    /**
     * 保存缓存对应的过期时间
     */
    private final Map<String, Long> cacheExpireRecord;

    public DawnSimpleCache() {
        cache = new ConcurrentHashMap<>();
        cacheExpireRecord = new ConcurrentHashMap<>();
    }

    public Pair<Boolean, Optional<?>> getFromCache(String key) {
        boolean cacheContainsKey = true;
        Object value = null;
        Long expireTime = cacheExpireRecord.get(key);
        // 如果存在这个Key
        if (expireTime != null) {
            // 如果数据已经过期,此处使用了延迟删除,只有查询发现过期了才会删除
            // 0L是特殊的,它代表永不过期
            if (expireTime != 0L && expireTime < System.currentTimeMillis()) {
                log.info("SIMPLE CACHE缓存过期:" + key);
                deleteCache(key);
                cacheContainsKey = false;
            } else {
                // 从缓存中获取数据
                value = cache.get(key);
            }
        } else {
            cacheContainsKey = false;
        }
        return Pair.of(cacheContainsKey, Optional.ofNullable(value));
    }

    public int deleteCache(String keyPrefix) {
        Set<String> keys = new HashSet<>();
        // 先查到以这个前缀开头的所有Key
        cache.forEach((k, v) -> {
            if (k.startsWith(keyPrefix)) {
                keys.add(k);
            }
        });
        // 遍历这些Key,依次清除
        keys.forEach(key -> {
            cacheExpireRecord.remove(key);
            cache.remove(key);
            log.info("SIMPLE CACHE缓存清除:" + key);
        });
        return keys.size();
    }

    public void setCache(String key, Object value, long timeToLive, TimeUnit timeUnit) {
        cache.put(key, value);
        // 记录失效时间
        if (timeToLive <= 0L) {
            cacheExpireRecord.put(key, 0L);
        } else {
            cacheExpireRecord.put(key, System.currentTimeMillis() + timeUnit.toMillis(timeToLive));
        }
    }
}

其中cacheExpireRecord这个Map的用途就是用来保存缓存的过期时间,代码中使用了延迟删除,只有查询发现过期了才会删除
,0L是特殊的,它代表永不过期。

这个SimpleCache代码简单,功能也简单,但对于一些简单轻量的缓存,却也足够使用了。

版权声明

知识共享许可协议 本文章由作者“衡于墨”创作,转载请注明出处,未经允许禁止用于商业用途

本作品采用 知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议 进行许可。
发布时间:2021年06月13日 21:32:08

评论区#

还没有评论哦,期待您的评论!

关闭特效