java本地内存缓存类LocalCache

   本次介绍的本地内存缓存和ExpiryMap(之前写过这个博客)差不多。

ExpiryMap

具体介绍:

1)调用save()方法,可以添加缓存,并指定过期时间。

2)调用load()方法可以从本地缓存中读取数据,如果缓存过期了,则返回null,业务层需要从数据库等持久化存储库中查询数据,并再次缓存起来。

3)也可以调用clearCache()方法手动删除指定key缓存。

4)定时任务会每隔5分钟定时清理一次已过期的缓存数据。

工具类(可以直接拿来用)

import com.alibaba.fastjson.parser.ParserConfig;
import com.alibaba.fastjson.util.TypeUtils;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import lombok.extern.slf4j.Slf4j;
 
/**
 * 本地内存缓存工具类
 */
@Slf4j
public class LocalCacheUtil {
 
  private LocalCacheUtil() {
 
  }
 
  // 定时任务执行器
  private static ScheduledExecutorService refreshExecutor = new ScheduledThreadPoolExecutor(1, Executors.defaultThreadFactory());
 
  // 当前缓存
  private static volatile ConcurrentHashMap<String, CacheElement<Object>> cacheMap = new ConcurrentHashMap<>();
 
  // 缓存对象
  static class CacheElement<T extends Object> {
 
    // 缓存值
    private T value;
 
    // 过期时间
    private Long expire;
 
    /**
     * 有参数构造方法
     *
     * @param value 缓存的值
     * @param timeout 过期时间。单位:ms
     */
    public CacheElement(T value, Long timeout) {
      this.value = value;
      this.expire = System.currentTimeMillis() + timeout;
    }
 
    /**
     * 判断缓存是否过期
     */
    public boolean isOvertime() {
      return expire < System.currentTimeMillis();
    }
  }
 
  /**
   * 读取本地缓存
   *
   * @param key 缓存key
   * @param requireClass 缓存值对应class
   */
  public static <T extends Object> T load(String key, Class<T> requireClass) {
    CacheElement<Object> e = cacheMap.get(key);
    //过期返回null
    if (null == e || e.isOvertime()) {
      return null;
    }
    return TypeUtils.cast(e.value, requireClass, ParserConfig.getGlobalInstance());
  }
 
  /**
   * 保存至本地缓存
   *
   * @param key 缓存key
   * @param value 缓存值
   * @param timeout 过期时间。单位:ms
   */
  public static <T extends Object> void save(String key, T value, Long timeout) {
    cacheMap.put(key, new CacheElement<>(value, timeout));
  }
 
  /**
   * 手动清除key对应的本地缓存
   */
  public static void clearCache(String key) {
    cacheMap.put(key, null);
  }
 
  /**
   * 定时(每5分钟)清理一次缓存中过期的数据
   */
  static {
    refreshExecutor.scheduleAtFixedRate(() -> {
      ConcurrentHashMap<String, CacheElement<Object>> newCache = new ConcurrentHashMap<>();
      for (Map.Entry<String, CacheElement<Object>> e : cacheMap.entrySet()) {
        // 丢弃已经过期的数据
        if (e.getValue().isOvertime()) {
          continue;
        }
        newCache.put(e.getKey(), e.getValue());
      }
      cacheMap = newCache;
    }, 0, 5 * 60, TimeUnit.SECONDS);
  }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值