如何在不同Java类文件中使用同一个Caffeine Cache缓存实例?
问题核心原因
你当前的写法中,cache是Main类的实例成员变量,每调用一次new Main()都会初始化一个全新的Cache对象,不同实例持有的缓存完全独立,自然无法跨实例读取存储的内容。
解决方案
以下提供两种适配不同场景的实现方式:
方案1:静态缓存(简单快速实现)
直接将缓存声明为Main类的静态成员,和类本身绑定而非类实例绑定,全局只有唯一一份:
public class Main { // 静态缓存,全局唯一 public static final Cache<String, String> CACHE = Caffeine.newBuilder() .expireAfterWrite(2, TimeUnit.HOURS) .maximumSize(250) .build(); public static void main(String[] args) { // 直接通过类名调用即可 CACHE.getIfPresent("key"); } }
其他类直接访问静态成员即可,不需要新建Main实例:
import Main; public class Second { public static void main(String[] args) { Main.CACHE.put("key", "value"); } }
注意:该方案实现简单,但静态变量生命周期和类加载器绑定,如果你的插件需要支持热加载,可能会出现内存泄漏问题,更适合小型简单插件使用。
方案2:基于插件主类单例获取(适配Minecraft插件场景)
你正在开发Minecraft插件,插件的主类在服务器加载插件时只会生成一个唯一实例,更符合规范的做法是通过主类单例传递缓存实例:
首先改造主类,添加单例获取和缓存获取方法:
public class Main extends JavaPlugin { private static Main INSTANCE; private Cache<String, String> cache; @Override public void onEnable() { INSTANCE = this; // 插件启用时初始化缓存 cache = Caffeine.newBuilder() .expireAfterWrite(2, TimeUnit.HOURS) .maximumSize(250) .build(); } @Override public void onDisable() { // 插件卸载时清理缓存,避免内存泄漏 cache.invalidateAll(); } public static Main getInstance() { return INSTANCE; } public Cache<String, String> getCache() { return cache; } }
其他类直接通过主类单例获取缓存即可:
public class Second { public void handleEvent() { // 直接使用全局唯一的缓存实例 Main.getInstance().getCache().put("key", "value"); String value = Main.getInstance().getCache().getIfPresent("key"); } }
额外注意事项
- Java语法中,单引号只能用来包裹单个字符,字符串需要用双引号包裹,你示例代码中的
put('key', 'value')属于语法错误,需要修正为put("key", "value") - Caffeine缓存本身是线程安全的,Minecraft插件的异步事件、异步任务场景可以直接使用,不需要额外加锁。
内容的提问来源于stack exchange,提问作者Pro Poop
相关产品推荐
相关产品推荐

