[Java] Local (memory) cache actual combat--LocalCacheUtil.java

Ordinary is just two words: laziness and laziness;
success is just two words: hardship and diligence;
excellence is just two words: you and me.
Follow me to learn JAVA, spring family bucket and linux operation and maintenance knowledge from 0, and take you from an ignorant teenager to the peak of life, and marry Bai Fumei!
Follow the WeChat public account [ IT is very reliable  ], and share technical experience every day~ 

 

[Java] Local (memory) cache actual combat--LocalCache

      There are many ways to cache data, and there are also different storage media. Such as redis, cookie, session, memcache, etc., but here is a kind of object cache stored in memory, here called: LocalCache.

     Less gossip, the focus is on the code!

 

1 Cache tools

      I organized the code for local cache and formed a java tool class: LocalCacheUtil.java.

      1) Call the save() method, you can add a cache, and specify the expiration time.

      2) Call the load() method to read data from the local cache. If the cache expires, null is returned. The business layer needs to query the data from a persistent storage library such as a database and cache it again.

      3) You can also call the clearCache() method to manually delete the specified key cache.

      4) The scheduled task will periodically clean up expired cached data every 5 minutes.

package com.hc.alltest.localCache;

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);
  }
}

 

2 Test the local cache

      To cache a key in the local cache: name, value: Zhang San's data. Then read the cache data corresponding to the name key from the local cache in a loop.

package com.hc.alltest.localCache;

import lombok.extern.slf4j.Slf4j;
import org.springframework.util.StringUtils;

/**
 * 测试本地缓存
 */
@Slf4j
public class Main {

  public static void main(String[] args) throws Exception {
    //缓存数据
    LocalCacheUtil.save("name", "张三", 600L);
    while (true) {
      //从缓存读取数据
      String cacheValue = LocalCacheUtil.load("name", String.class);
      log.info("cacheValue:" + cacheValue);
      if(StringUtils.isEmpty(cacheValue)){
        break;
      }
      Thread.sleep(100L);
    }
  }
}

      Follow the WeChat public account and get free java and related video tutorials~

 

 

Guess you like

Origin blog.csdn.net/IT_Most/article/details/109169416