【问题标题】:Lightweight Java Object cache API [closed]轻量级 Java 对象缓存 API [关闭]
【发布时间】:2010-09-18 20:11:58
【问题描述】:

问题

我正在寻找 Java 内存中对象缓存 API。有什么建议吗?您过去使用过哪些解决方案?

当前

现在,我只是在使用地图:

Map cache = new HashMap<String, Object>();
cache.put("key", value);

要求

我需要扩展缓存以包含以下基本功能:

  • 最大尺寸
  • 生存时间

但是,我不需要更复杂的功能,例如:

  • 从多个进程访问(缓存服务器)
  • 持久性(到磁盘)

建议

内存缓存:

  • Guava CacheBuilder - 积极开发。看到这个presentation
  • LRUMap - 通过 API 配置。没有 TTL。不是为缓存而设计的。
  • whirlycache - XML 配置。邮件列表。最后更新于 2006 年。
  • cache4j - XML 配置。俄语文档。最后更新于 2006 年。

企业缓存:

  • JCS - 属性配置。丰富的文档。
  • Ehcache - XML 配置。广泛的文档。到目前为止,根据 Google 的点击率是最受欢迎的。

【问题讨论】:

  • 您能否编辑 Suggestions In-Memory 缓存部分以包含 Guava 缓存?我和你一样在寻找一个轻量级的缓存机制,发现了这个问题,但没有找到 Guava,因为它已经下降了。现在我使用了 guava 缓存包,它太棒了。
  • 完成。 :-) 很高兴你喜欢它!
  • 也许您还想考虑添加相对较新的cache2k。在他们的benchmarks page 上,据说它的性能比 ehcache 和 Guava 好得多。

标签: java caching


【解决方案1】:

EHCache 非常好。您可以创建内存缓存。查看他们的code samples,了解创建内存缓存的示例。您可以指定最大尺寸和生存时间。

EHCache 确实提供了一些高级功能,但如果您对使用它们不感兴趣,请不要使用它们。但是,如果您的要求发生变化,很高兴知道它们在那里。

这是一个内存缓存。在代码中创建,没有配置文件。

CacheManager cacheManager = CacheManager.getInstance();
int oneDay = 24 * 60 * 60;
Cache memoryOnlyCache = new Cache("name", 200, false, false, oneDay, oneDay);
cacheManager.addCache(memoryOnlyCache);

创建一个可以容纳 200 个元素的缓存,并且 ttl 为 24 小时。

【讨论】:

  • EHCache 是直接引用对象还是先序列化再反序列化对象?
  • EHCache 是不是重量级的解决方案?我们正在研究现有的缓存解决方案,以便在 Android 上实现 API 缓存。
  • 对于安卓来说太重了。我正在使用 Kitty 缓存,它非常完美!
  • @Stevet K,我知道这个缓存技术很晚,但我猜 getInstance() 被删除或更改了。
【解决方案2】:

我真的很喜欢Google Guava 附带的MapMaker (API)

JavaDoc 有一个非常简洁的示例,展示了它的易用性和强大功能:

ConcurrentMap<Key, Graph> graphs = new MapMaker()
   .concurrencyLevel(32)
   .softKeys()
   .weakValues()
   .expiration(30, TimeUnit.MINUTES)
   .makeComputingMap(
       new Function<Key, Graph>() {
         public Graph apply(Key key) {
           return createExpensiveGraph(key);
         }
       });

此外,Guava 10.0 版引入了更广泛的com.google.common.cache package(有一个nice wiki entry on how to use them)。

【讨论】:

【解决方案3】:

您还可以查看我的名为 KittyCache 的小型缓存库:

https://github.com/treeder/kitty-cache

有一些与 ehcache 相比的性能基准。

SimpleJPA 项目中用作二级缓存。

【讨论】:

  • 不错,但如果它只有 TTL。
  • 谢谢!只是我在想检查是否有人已经开源之前输入的代码:)
  • @RosdiKasim 实际上在 put() 调用上确实有 TTL,例如:cache.put("mykey", value, 500); 500 是 TTL。
  • @TravisR 嗯...,当时它没有 TTL.. :p
  • 啊,不知道那条评论是多久以前的了。
【解决方案4】:

您可以查看 LinkedHashMap 以实现无需第三方 jar 的简单缓存:

    Map <String, Foo> cache = new LinkedHashMap<String, Foo>(MAX_ENTRIES + 1, .75F, true) {

        public boolean removeEldestEntry(Map.Entry<String, Foo> eldest) {
            return size() > MAX_ENTRIES;
        }
    };

那么你就可以像从缓存中获取

    Foo foo = cache.get(key);
    if (foo == null && !cache.containsKey(key)) {
        try {
            FooDAO fooDAO = DAOFactory.getFooDAO(conn);
            foo = fooDAO.getFooByKey(key);
            cache.put(key, foo);
        } catch (SQLException sqle) {
            logger.error("[getFoo] SQL Exception when accessing Foo", sqle);
        }
    }

留给读者练习:)

【讨论】:

  • 我觉得这个方法没有TTL能力。不过,这将是一个很好的开始。
  • 是的,我会把 TTL 的东西作为读者练习的一部分:p - 当然,第三方库的测试远远超过你自己的测试。
【解决方案5】:

Guava 的 MapMaker 已被他们的 CacheBuilder 类取代。

【讨论】:

    【解决方案6】:

    JCS 是经过验证的。尽管就缓存机制而言它很轻,但您可能会深入研究实际代码并模仿它们在幕后对 HashMap 所做的事情,以完全满足您的需求,仅此而已。你似乎很清楚你在寻找什么。

    【讨论】:

    • 我假设您的意思是就缓存机制而言,它不是轻?不过,它似乎是最受欢迎的企业解决方案之一。
    【解决方案7】:

    memcached 有 Java 客户端。 http://www.danga.com/memcached/ 需要单独的进程作为缓存服务器,但功能强大。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-07-21
      • 2011-10-25
      • 1970-01-01
      • 1970-01-01
      • 2012-01-25
      • 2011-08-31
      • 1970-01-01
      • 2016-06-01
      相关资源
      最近更新 更多