Java 中哪种数据结构最适合实现内存中对象缓存,其中对象具有单独的过期时间?
基本上对于缓存,我可以使用提供 put 和 get 方法的 Map(其中键可以是字符串),并使用“时间戳”+“对象”对的有序列表来管理过期时间。因此,清理线程可以检查第一个列表条目,并在其过期时间过后删除该对象。 (删除第一个元素应该在 O(1) 时间内)
Which data structure in Java would be best to implement an in-memory object cache, where objects have an individual expiration time?
Basically for the cache I could use a Map (where key could be a String) which offers the put and get methods, and use a ordered list of "timestamp"+"object" pairs to manage the expiration time. So a cleanup thread could check the first list entry and delete the object when its expiration time passed. (Deletion of the first element should be in O(1) time)
发布评论
评论(6)
您所描述的构建基本上是我的 ExpiringMap。还有其他类似的实现,例如 Guava(请参阅 CacheBuilder) - 尽管我不认为它像 ExpiringMap 那样支持每个条目过期。
What you're describing building is basically my ExpiringMap. There are other similar implementations, such as Guava (see CacheBuilder) - though I don't believe it supports per-entry expiration as ExpiringMap does.
缓存框架现在已经相当成熟:
但是,如果您坚持重新发明轮子,请记住考虑内存利用率。我经常看到实施不当的缓存 (
HashMap
) 实际上会导致内存泄漏。请参阅 Cowan 的答案:Java 的WeakHashMap 和缓存:为什么它引用键,而不是值?
Caching frameworks are pretty mature now:
However, if you insist on reinventing the wheel, remember to account for memory utilisation. All too often I see a badly implemented cache (
HashMap
) effectively turn into a memory leak.See Cowan's answer here: Java's WeakHashMap and caching: Why is it referencing the keys, not the values?
我会考虑使用现有的库,例如 ehcache。
但是,如果您想编写自己的线程,我不会使用后台线程,除非您需要它,因为它会增加复杂性。相反,我会让前台线程删除过期的条目。
如果您只需要 LRU 缓存,我会使用 LinkedHashMap。但是,如果您想要定时过期,我会使用带有
PriorityQueue
的HashMap
(这样您就可以检查下一个过期条目是否已过期)I would consider using an existing library like
ehcache
.However, if you want to write your own, I would not use a background thread unless you need it as it adds complexity. Instead I would have the foreground thread remove expired entries.
I would use
LinkedHashMap
if you just need an LRU cache. However if you want timed expiry, I would use aHashMap
with aPriorityQueue
(so you can check whether the next to expire entry has expired)Guava Cachebuilder :
由于 WeekHashmap 不适合缓存,但您始终可以使用
Map>
,其值符合 GC 的周引用条件。最重要的是,我们始终将 EhCache 、Memcached 和 coherence 作为流行的选择。
Guava Cachebuilder :
Since WeekHashmap doesn't fit caching but you can always utilize
Map<K,WeakReference<V>>
whose value become eligible for GC for week references.Above all we always have EhCache ,Memcached and coherence as popular choice.
我认为你的决定是正确的。
确切地说,我会使用 HashMap。
I think your decision is right.
I would be using HashMap to be exact.
正如前面的答案中提到的,最好使用流行的内存缓存之一,如 EhCache、Memcached 等。
但是正如您希望通过自己的缓存实现它一样,该缓存具有对象过期功能且时间复杂度较低,我尝试像这样实现它 - (非常感谢任何测试评论/建议)..
As mentioned in previous answers, it is better to use one of the popular in-memory caches like EhCache, Memcached etc.
But just as you wanted implement it by your own cache which has the object expiry feature and less time complexity, I tried to implement it like this - (any test reviews/suggestions much appreciated)..