本文介绍了Guava MapMaker是否可以为工厂方法设置maximumSize(0)?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用MapMaker在应用程序中实现数据对象的缓存:

I'm using the MapMaker to implement caching of data objects in my application:

public class DataObjectCache<DO extends MyDataObject> {

    private final ConcurrentMap<String, DO> innerCache;

    public DataObjectCache(Class<DO> doClass) {

        Function<String, DO> loadFunction = new Function<String, DO>() {
            @Override
            public DO apply(String id) {
                //load and return DO instance
            }
        };

        innerCache = new MapMaker()
             .softValues()
             .makeComputingMap(loadFunction);
    }

    private DO getDataObject(String id) {
        return innerCache.get(id);
    }

    private void putDataObject(DO dataObject) {
        innerCache.putIfAbsent(dataObject.getID(), dataObject);
    }
}

将为每个数据对象类实例化其中一个DataObjectCache,并将它们使用Class对象作为键保存在主Map中.

One of these DataObjectCaches would be instantiated for each data object class, and they would be kept in a master Map, using the Class objects as keys.

有一小部分我不想缓存其实例的数据对象类.但是,我仍然希望它们可以由函数调用的同一代码实例化,并且仍然需要并发性才能清楚地加载它们.

There's a minority of data object classes whose instances I don't want cached. However I would still like them to be instantiated by the same code, which the Function is calling, and would still need concurrency in regard to loading them distinctly.

在这些情况下,我想知道是否可以将地图的最大大小设置为0,以便立即清除条目,但仍然利用地图的原子计算方面.这是一个好主意吗?效率低下吗?

In these cases, I'm wondering if I can just set the maximum size of the map to 0, so that entries are evicted immediately, but still take advantage of the atomic computing aspects of the map. Is this a good idea? Inefficient?

我意识到,如果我在加载条目后立即逐出条目,则无法保证它们的加载是不同的-如果Map不能跟踪它们,则具有相同ID的对象的多个实例可能会在其周围浮动环境.因此,我不想这样做,而不是对不想占用缓存的对象类型使用弱值而不是软值-让我知道是否有人对此表示怀疑.

I realized that if I evicted entries immediately after loading them, there's no way to guarantee they are distinctly loaded - if the Map isn't keeping track of them, multiple instances of an object with the same ID could be floating around the environment. So instead of doing this, I think I'll use weak values instead of soft values for the types of objects I don't want taking up cache - let me know if anyone has an opinion on this.

推荐答案

根据您的编辑,听起来您正在寻找的是一个合作伙伴.一个合作者返回一个代表实例;对于根据您的equals方法相等的所有对象,Interner.intern将返回相同的对象.从Javadoc:

In light of your edit, it sounds like what you're looking for is an interner. An interner returns a representative instance; the same object will be returned by Interner.intern for all objects that are equal according to your equals method. From the Javadoc:

请参见 http://guava -libraries.googlecode.com/svn/trunk/javadoc/com/google/common/collect/Interner.html http://guava-libraries.googlecode.com/svn/trunk/javadoc/com/google/common/collect/Interners.html

也就是说,这取决于您说不希望它被缓存时的含义.如果您确实希望每次都返回一个新实例,则必须有多个浮动"的等效对象实例.

That said, it depends what you mean when you say you don't want it cached. If you truly want to return a fresh instance every time, then you'd have to have multiple instances of equivalent objects "floating around".

Interning保留了一个实例(因此它可以返回相同的实例),因此它仍然是一种缓存.我想知道为什么要避免缓存.如果是由于对象的大小,则可以使用弱互通;当该实例不再被引用时,它将可用于GC.再说一次,只需使用具有弱值的MapMaker映射也可以完成此操作.

Interning is holding on to an instance (so it can return the same one), so it is still sort of a cache. I would want to know why you want to avoid caching. If it is because of the size of the objects, you can use a weak interner; the instance will be available for GC when it's no longer referenced. Then again, simply using a MapMaker map with weak values would accomplish that as well.

另一方面,如果您不希望缓存的原因是因为您的数据易于更改,那么可以通过实习来解决.我可以想象您想要的是每次都检索对象,然后对其进行实习.如果该对象等于已缓存的对象,则交互者将仅返回现有实例.如果不同,则合作伙伴将缓存新的缓存.然后,您的责任是在对象上编写一个equals方法,该方法满足使用新实例与实习实例的要求.

If, on the other hand, the reason you don't want to cache is because your data is liable to change, interning could be your answer. I would imagine what you'd want is to retrieve the object every time, and then intern it. If the object is equal to the cached one, the interner would simply return the existing instance. If it is different, the interner would cache the new one. Your responsibility then would be to write an equals method on your object that meets the requirements for using a new vs interned instance.

这篇关于Guava MapMaker是否可以为工厂方法设置maximumSize(0)?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-16 06:11