具有弱值的HashMap

Add*_*dev 23 java android weak-references hashmap

我正在为持久存储的对象实现缓存.这个想法是:

  • 方法 getObjectFromPersistence(long id); ///Takes about 3 seconds
  • 方法 getObjectFromCache(long id) //Instantly

并有一个方法:getObject(long id)使用以下伪代码:

synchronized(this){
    CustomObject result= getObjectFromCache(id)
    if (result==null){
       result=getObjectFromPersistence(id);
       addToCache(result);
    }
    return result;
}
Run Code Online (Sandbox Code Playgroud)

但我需要允许垃圾收集器收集CustomObject.到目前为止,我正在使用一个HashMap<Long,WeakReference<CustomObject>实现.问题是随着时间的推移HashMap变得空洞WeakReferences.

我已经检查了WeakHashMap但是键很弱(并且值仍然是强引用)所以使用WeakReferences的longs没有任何意义.

什么是解决这个问题的最佳解决方案?是否有一些"逆WeakHashMap"或类似的东西?

谢谢

Joa*_*uer 27

您可以使用Guava MapMaker:

ConcurrentMap<Long, CustomObject> graphs = new MapMaker()
   .weakValues()
   .makeMap();
Run Code Online (Sandbox Code Playgroud)

您甚至可以通过替换以下内容来包含计算部分makeMap():

   .makeComputingMap(
       new Function<Long, CustomObject>() {
         public CustomObject apply(Long id) {
           return getObjectFromPersistence(id);
         }
       });
Run Code Online (Sandbox Code Playgroud)

由于您所写的内容看起来很像缓存,因此更新,更专业Cache(通过a构建CacheBuilder)可能与您更相关.它不Map直接实现接口,但为缓存提供了更多可能需要的控件.

您可以参考这个以获取有关如何使用CacheBuilder的详细信息,以下是快速访问的示例:

LoadingCache<Integer, String> cache = CacheBuilder.newBuilder()
   .maximumSize(100)
   .expireAfterWrite(10, TimeUnit.MINUTES)
   .build(
       new CacheLoader<Integer, String>() {
           @Override
           public String load(Integer id) throws Exception {
               return "value";
           }
       }
   ); 
Run Code Online (Sandbox Code Playgroud)


Joh*_*rak 5

在收集其参考时,在施工时WeakReference添加A.ReferenceQueue

你可以pollReferenceQueue每当你访问缓存,并举行HashMap<WeakReference<CustomObject>,Long>知道,如果引用在队列中找到要删除的条目.

或者,如果不经常使用缓存,则可以在单独的线程中查看队列.