采用static Map、ConcurrentHashMap实现数据缓存

简介: 在java项目开发中考虑到在使用HashMap在并发时会出现不正确行为,自己编写了采用static ConcurrentHashMap来完成静态缓存的处理,目的是为了能够用来处理高并发的线程安全类,如有问题请各指教: package com.

在java项目开发中考虑到在使用HashMap在并发时会出现不正确行为,自己编写了采用static ConcurrentHashMap来完成静态缓存的处理,目的是为了能够用来处理高并发的线程安全类,如有问题请各指教:

package com.hlwfarm.market.service;

import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.ctrip.market.commom.CLogger;
import com.ctrip.market.commom.DateTimeUtil;
import com.ctrip.market.commom.Distance;
import com.ctrip.market.commom.ServiceFactory;
import com.ctrip.market.entity.GfMsgscene;

public class MapCacheManager {

  private static CLogger<MapCacheManager> logger = new CLogger<MapCacheManager>();
  private volatile long updateTime = 0L;// 更新缓存时记录的时间
  private volatile boolean updateFlag = true;// 正在更新时的阀门,为false时表示当前没有更新缓存,为true时表示当前正在更新缓存
  private static Map<String, Object> cacheMap = new ConcurrentHashMap<String, Object>();// 缓存容器

  private static GfMsgsceneService gfMsgsceneService = (GfMsgsceneService) ServiceFactory
      .getInstance("gfMsgsceneService");// 场景信息

  public MapCacheManager() {
    this.LoadCache();// 加载缓存
    updateTime = System.currentTimeMillis();// 缓存更新时间
  }

  /**
   * 装载缓存
   */
  private void LoadCache() {

    this.updateFlag = true;// 正在更新

    /********** 数据处理,将数据放入cacheMap缓存中 **begin ******/

    List<GfMsgscene> sceneList = gfMsgsceneService.queryByDateList();
    cacheMap.put("sceneList", sceneList);
    cacheMap.put("key2", "value2");

    logger.info("更新缓存完成", "更新缓存完成, date=" + DateTimeUtil.GetNowDateString());
    System.out.println("更新缓存完成:" + DateTimeUtil.GetNowDateString());

    /********** 数据处理,将数据放入cacheMap缓存中 ***end *******/
    this.updateFlag = false;// 更新已完成

  }

  /**
   * 返回缓存单个对象
   * 
   * @return
   */
  public Object getObjectCache(String key) {

    long currentTime = System.currentTimeMillis();
    synchronized (this) {

      // 如果当前缓存正在更新或者缓存超出时限,需重新加载
      if (this.IsTimeOut(currentTime)) {

        this.ReLoadCache();
        this.updateTime = currentTime;
      }
    }

    return this.cacheMap.get(key);
  }

  private boolean IsTimeOut(long currentTime) {
    logger.info("up", "up=" + (currentTime - this.updateTime));
    return ((currentTime - this.updateTime) >= 1000 * 60 * 10);// 超过时限,缓存1分钟
  }

  /**
   * 获取缓存项大小
   * 
   * @return
   */
  private int getCacheSize() {
    return cacheMap.size();
  }

  /**
   * 获取更新时间
   * 
   * @return
   */
  private long getUpdateTime() {
    return this.updateTime;
  }

  /**
   * 获取更新标志
   * 
   * @return
   */
  private boolean getUpdateFlag() {
    return this.updateFlag;
  }

  /**
   * 重新装载
   */
  private void ReLoadCache() {
    this.cacheMap.clear();
    this.LoadCache();
  }


  /**
    * @ClassName: CacheKeyEnum
    * @Description: 缓存数据key枚举
    */
  public enum CacheKeyEnum {
    sceneList,
  }

}

  /**
   * 返回缓存全部
   * 
   * @return
   */
  public Map<String, Object> getMapCache() {

    long currentTime = System.currentTimeMillis();
    // 如果当前缓存正在更新或者缓存超出时限,需重新加载
    if (this.IsTimeOut(currentTime)) {
      synchronized (this) {
        this.ReLoadCache();
        this.updateTime = currentTime;
      }
    }

    return this.cacheMap;
  }

单元测试:

public class CacheTest {

 private static MapCacheManager cache = new MapCacheManager();

  @Test
  public void test() {
    for (int i = 0; i < 10; i++) {
      Map<String, Object> cacheMap = new ConcurrentHashMap<String, Object>();
      cacheMap = cache.getMapCache();
      Set<String> set = cacheMap.keySet();
      Iterator<String> it = set.iterator();

      while (it.hasNext()) {
        String key = it.next();
        System.out.println(key + "=" + JsonSerializer.serialize(cacheMap.get(key)));
      }
    }
  }

}
目录
相关文章
|
1月前
|
缓存
【工具篇】使用concurrentHashMap实现缓存工具类
【工具篇】使用concurrentHashMap实现缓存工具类
|
4月前
|
存储 缓存 分布式计算
亿级数据如何分钟级别写入缓存?
亿级数据如何分钟级别写入缓存?
30 0
|
7月前
|
缓存 达摩院 Kubernetes
数据缓存系列分享(六):通义千问Qwen-14B大模型快速体验
阿里达摩院近期对通义千问大模型 Qwen-14B 进行了开源(之前开源的是Qwen-7B模型),目前在ModelScope和HuggingFace上均可直接下载。关于Qwen-7B的搭建可以参考我们之前的文章:数据缓存系列分享(五):开源大语言模型通义千问快速体验版,本文将使用一样的方式打开Qwen-14B,快速体验一下。
1190 0
数据缓存系列分享(六):通义千问Qwen-14B大模型快速体验
|
1月前
|
缓存 NoSQL Java
【九】springboot整合redis实现启动服务时热点数据保存在全局和缓存
【九】springboot整合redis实现启动服务时热点数据保存在全局和缓存
40 0
|
2月前
|
存储 缓存 算法
使用Java实现高效的数据缓存系统
【2月更文挑战第3天】在大规模的应用程序中,数据缓存是提高应用程序性能的一种重要方法。本文介绍了如何使用Java实现高效的数据缓存系统。我们将讨论缓存的设计原则和缓存算法的选择,同时详细说明如何使用Java内置的缓存库和其他开源工具来构建一个可靠、高效的数据缓存系统。
|
6月前
|
消息中间件 缓存 Java
Java 最常见的面试题:怎么保证缓存和数据库数据的一致性?
Java 最常见的面试题:怎么保证缓存和数据库数据的一致性?
|
3月前
|
canal 缓存 关系型数据库
Springcloud Alibaba使用Canal将Mysql数据实时同步到Redis保证缓存的一致性
canal [kə'næl] ,译意为水道/管道/沟渠,主要用途是基于 MySQL 数据库增量日志解析,提供增量数据订阅和消费。其诞生的背景是早期阿里巴巴因为杭州和美国双机房部署,存在跨机房同步的业务需求,实现方式主要是基于业务 trigger 获取增量变更。从 2010 年开始,业务逐步尝试数据库日志解析获取增量变更进行同步,由此衍生出了大量的数据库增量订阅和消费业务。
|
4月前
|
SQL 缓存 分布式计算
Apache Zeppelin系列教程第九篇——Zeppelin NoteBook数据缓存
Apache Zeppelin系列教程第九篇——Zeppelin NoteBook数据缓存
103 0
|
4月前
|
缓存 Java 关系型数据库
Spring Boot与Spring中的数据缓存Cache支持与实战(附源码)
Spring Boot与Spring中的数据缓存Cache支持与实战(附源码)
49 0
Spring Boot与Spring中的数据缓存Cache支持与实战(附源码)
|
4月前
|
缓存 Cloud Native 调度
Fluid支持分层数据缓存本地性调度(Tiered Locality Scheduling)
依赖容器化带来的高效部署、敏捷迭代,以及云计算在资源成本和弹性扩展方面的天然优势,以 Kubernetes 为代表的云原生编排框架吸引着越来越多的 AI 与大数据应用在其上部署和运行。但是数据密集型应用计算框架的设计理念和云原生灵活的应用编排的分歧,导致了数据访问和计算瓶颈。 CNCF开源项目Fluid作为 AI 与大数据云原生应用提供一层高效便捷的数据抽象,将数据从存储抽象出来,针对具体的场景(比如大模型),加速计算访问数据。
742 0