Java将数据放到缓存中,当需要从缓存中获取数据的时候获取不到?

作者站长头像
站长
· 阅读数 18

我在项目中使用了如下代码,将一些数据放到了缓存中,当有地方需要调用getBAsset方法获取数据的时候,发现assetBuffer 中数据为空,这是什么原因呢?当出现该问题的时候,我登录到项目部署的服务器上,查看服务器内存,发现可用内存只有100多M了,buffer内存占了3个G,服务器总内存为8个G,然后我把项目停了之后,将buffer内存清除之后,重新启动项目之后,再次调用getBAsset方法,assetBuffer是有数据的。(放入到缓存中的数据大概有16w左右)项目是用tomcat启动的,启动参数是这样配置的,给tomcat分了3G左右

Java将数据放到缓存中,当需要从缓存中获取数据的时候获取不到?

想请问大佬们,为什么会出现getBAsset方法拿不到数据呢?是因为系统内存不足了,java内存中的数据被清空了?目前还暂不考虑加redis组件,感觉加了redis组件会解决此问题

/**
 * 缓存
 */
@Component
@Order(1)
@Slf4j
public class ScenarioBuffer implements IActionListener, ApplicationRunner {
    /**
     * 资产缓存
     * 系统启动时初始化,当资产增删改时,同步更新它;
     */
    private static Map<String, List<Asset>> assetBuffer = Collections.synchronizedMap(new HashMap<String, List<Asset>>());


    private static ScenarioBuffer instance = new ScenarioBuffer();

    public static ScenarioBuffer getInstance() {
        return instance;
    }

    /**
     * 从缓存中获取资产
     *
     * @param groupId
     * @return
     */
    public static List<Asset> getBAsset(String groupId) {
        if (assetBuffer.containsKey(groupId)) {
            return assetBuffer.get(groupId);
        }
        return null;
    }

    @Override
    public void run(ApplicationArguments args) throws Exception {
        IAssetService assetService = SpringUtil.getBean(IAssetService.class);
        List<Asset> assetList = assetService.list();
        assetBuffer.put("key",assetList);
    }

}
回复
1个回答
avatar
test
2024-06-26

另外,你这类都使用@Component注解,Bean默认就是单例,getInstance()多此一举?

需要看下你在调用时怎么做的,理论上你最好使用@Resource之类注解进行依赖注入,而不是使用getInstance()这种方式。

既然是单例,就无需考虑多实例场景,故static也可省略。


另外,推挤你使用@PostConstruct或者InitializingBean,来完成一些Bean的业务类初始化动作。

既然使用Spring,就好好去用它


推荐你使用这种方式

@Component
public class ScenarioBuffer implements IActionListener {
    
    // 没必要使用 static
    // public static List<Asset> getBAsset(String groupId) {
    public List<Asset> getBAsset(String groupId) {
        if (assetBuffer.containsKey(groupId)) {
            return assetBuffer.get(groupId);
        }
        return null;
    }
}


@Service
public class XxxService {
    // 注入依赖
    @Resource
    private ScenarioBuffer scenarioBuffer;
    
    public void xxx() {
        // 直接使用即可
        final List<Asset> asset = scenarioBuffer.getBAsset("xxx");
    }
}
回复
likes
适合作为回答的
  • 经过验证的有效解决办法
  • 自己的经验指引,对解决问题有帮助
  • 遵循 Markdown 语法排版,代码语义正确
不该作为回答的
  • 询问内容细节或回复楼层
  • 与题目无关的内容
  • “赞”“顶”“同问”“看手册”“解决了没”等毫无意义的内容