本文共 4232 字,大约阅读时间需要 14 分钟。
在大数据下,我们在追求性能的时候往往离不开缓存的使用,可是怎么使用缓存才能更高效呢?这一直是我们在追求解决的一个问题,今天我们就来介绍一种比较高效的使用方法。
public class ConfigCache { private static final Logger log = LoggerFactory .getLogger(ConfigCache.class); /** 科目缓存 */ private static Map> TITLE_MAP = new HashMap<>(); private static ScheduledExecutorService executorService = Executors .newScheduledThreadPool( 1, new NamedThreadFactory( "bonus-config-cache", true)); /** 科目DAO */ @Resource private TitleDAO titleDAO; /** * 初始化,注入配置文件中启动时加载 */ public void init() { log.debug("load p-general config information!"); reload(); executorService.scheduleWithFixedDelay(new Runnable() { @Override public void run() { log.info("reload p-general config information!"); try { reload(); } catch (Exception ex) { log.warn("reload p-general config occurs exception, wait for next time"); } } }, 5, 5, TimeUnit.MINUTES); } /** * 加载缓存 */ public void reload() { // 从数据中查出科目信息 List titleDOList = titleDAO.selectAll(); HashSet titleSet = new HashSet<>(); for (TitleDO titleDO : titleDOList) { titleSet.add(titleDO.getReconInst()); } for (String str : titleSet) { Map map = new HashMap<>(); for (TitleDO titleDO : titleDOList) { if (StringUtils.equals(str, titleDO.getReconInst())) { map.put(String.format("%s%s%s", titleDO.getTitleCode(), titleDO.getReconInst(), titleDO.getLedgerType()), titleDO); } } TITLE_MAP.put(str, map); } } /** * 根据班级获取科目列表 * * @param reconInst 班级 * @return 科目列表 */ public List getTitleList(String reconInst) { Assert.notBlank(reconInst, "归属机构不能为空"); List list = new ArrayList<>(); // 存在缓存直接取值 if (TITLE_MAP.containsKey(reconInst)) { Map map = TITLE_MAP.get(reconInst); Iterator > it = map.entrySet().iterator(); while (it.hasNext()) { list.add(it.next().getValue()); } return list; } // 不存在缓存,去数据库查,然后放到缓存 if (!TITLE_MAP.containsKey(reconInst)) { Map condParam = new HashMap (); condParam.put("reconInst", reconInst); condParam.put("titleStatus", TitleStatusEnum.OPEN.getCode()); list = titleDAO.selectListByCond(condParam); Map map = new HashMap<>(); for (TitleDO titleDO : list) { map.put( String.format("%s%s%s", titleDO.getTitleCode(), titleDO.getReconInst(), titleDO.getLedgerType()), titleDO); } TITLE_MAP.put(reconInst, map); } return list; }
/** 缓存工具类 */@Resourceprivate ConfigCache configCache;public void test(){ TitleDO titleDO = null; String className="1"; try { //根据科班级查询出科目信息 titleDO = configCache.getTitleList(className); } catch (Exception e) { log.info("configCache.getTitleList()--利用缓存根据班级查询出科目信息失败", e); }}
我们看代码,特别的地方就是有个单线程的定时任务。这样我们可以保证所需的数据在缓存里基本是能找到的,减少了数据库的访问次数,从而使性能更优。
scheduleWithFixedDelayScheduledFuture scheduleWithFixedDelay(Runnable command, long initialDelay, long delay, TimeUnit unit)//参数://command - 要执行的任务//initialDelay - 首次执行的延迟时间//delay - 一次执行终止和下一次执行开始之间的延迟//unit - initialDelay 和 delay 参数的时间单
此方法是创建并执行一个在给定初始延迟后首次启用的定期操作,随后,在每一次执行终止和下一次执行开始之间都存在给定的延迟。如果任务的任一执行遇到异常,就会取消后续执行。否则,只能通过执行程序的取消或终止方法来终止该任务。
我们在性能优化的时候总是要考虑数据库的性能,因为在数据爆炸的这个年代,我们系统的瓶颈都在数据库。所以降低了数据库的损耗就会是性能得到很大提升。
转载地址:http://nfmei.baihongyu.com/