利用Hutool-cache来改造本地缓存数据

程序中有个从字典表获取数据的service -- TDicdataServiceImpl。

考虑到频繁获取字典数据,后来做了本地缓存。实现方案是利用ScheduledThreadPoolExecutor#schedule 。 在频繁访问这个方法过程中,设定每10分钟清理内存数据。

package com.cn.yft.ora.service.impl;

import com.cn.yft.ora.dao.TDicdataDAO;
import com.cn.yft.ora.entity.TDicdata;
import com.cn.yft.ora.service.TDicdataService;
import com.yft.util.StringUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.List;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

@Slf4j
@Service
public class TDicdataServiceImpl implements TDicdataService {

    private static HashMap<String,List<TDicdata>> cacheByDicmemo = new HashMap<>();
    private static ScheduledThreadPoolExecutor executor = new ScheduledThreadPoolExecutor(1);
@Autowired private TDicdataDAO tDicdataDAO; @SuppressWarnings("unchecked") @Override public List<TDicdata> selectByDicmemo(String dicmemo) { List<TDicdata> list = null; if(StringUtil.isEmpty(dicmemo)) return null; list = cacheByDicmemo.get(dicmemo); if(list == null || list.size() == 0){ list = this.tDicdataDAO.selectByDicDesc(dicmemo); cacheByDicmemo.put(dicmemo, list); } if(executor.getActiveCount()+executor.getQueue().size()==0) { executor.schedule(this::cacheByDicmemoClean,10, TimeUnit.MINUTES); } return list; }
@Override // @Scheduled(cron = "0 0/10 * * * ?") 注解@Scheduled对spring无效,需在spring.xml单独配置CronTriggerBean public void cacheByDicmemoClean() { if(!cacheByDicmemo.isEmpty()) { int size=cacheByDicmemo.size(); cacheByDicmemo.clear(); log.info("#字典缓存已清空---清空缓存---本地缓存--已清空本地内存数据{}条", size); } } }

 

说来真巧。上面缓存优化是在2020年年底改造的。 而今适逢一年,旧历2021年的年底,使用Hutool-cache的LFUCache来再做一次改造升级。

package com.cn.yft.ora.service.impl;

import cn.hutool.cache.CacheUtil;
import cn.hutool.cache.impl.LFUCache;
import com.cn.yft.ora.dao.TDicdataDAO;
import com.cn.yft.ora.entity.TDicdata;
import com.cn.yft.ora.service.TDicdataService;
import com.yft.util.StringUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import sun.reflect.generics.reflectiveObjects.NotImplementedException;

import java.util.HashMap;
import java.util.List;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

@Slf4j
@Service
public class TDicdataServiceImpl implements TDicdataService {

    // 缓存TTL:10分钟
    private static LFUCache<String,List<TDicdata>> cacheByDicmemo = CacheUtil.newLFUCache(16, TimeUnit.MINUTES.toMillis(10));

    @Autowired
    private TDicdataDAO tDicdataDAO;

    @SuppressWarnings("unchecked")
    @Override
    public List<TDicdata> selectByDicmemo(String dicmemo) {
        List<TDicdata> list = null;
        if(StringUtil.isEmpty(dicmemo)) return null;
        list = cacheByDicmemo.get(dicmemo);
        if(list == null || list.size() == 0){
            list = this.tDicdataDAO.selectByDicDesc(dicmemo);
            log.debug("获取key={},结果条数={}", dicmemo, list.size());
            cacheByDicmemo.put(dicmemo, list);
        }
        return list;
    }
    @Override
    public void cacheByDicmemoClean() {
        throw new NotImplementedException();
    }
}

 

上一篇:BUUCTF:[CFI-CTF 2018]webLogon capture


下一篇:支持flash的浏览器,谷歌浏览器Chrome、火狐浏览器Firefox