我的理想缓存使用番石榴
2022-09-02 10:57:07
在过去的几周里,我一直在断断续续地尝试使用番石榴的MapMaker找到理想的缓存实现。在这里和这里看到我之前的两个问题,以遵循我的思考过程。
根据我所学到的知识,我的下一次尝试是放弃软值,转而使用maxSize和perupAfterAccess:
ConcurrentMap<String, MyObject> cache = new MapMaker()
.maximumSize(MAXIMUM_SIZE)
.expireAfterAccess(MINUTES_TO_EXPIRY, TimeUnit.MINUTES)
.makeComputingMap(loadFunction);
哪里
Function<String, MyObject> loadFunction = new Function<String, MyObject>() {
@Override
public MyObject apply(String uidKey) {
return getFromDataBase(uidKey);
}
};
但是,我仍然在努力解决的一个剩余问题是,一旦时间到了,这个实现也会逐出对象,即使它们很强地可访问。这可能会导致具有相同UID的多个对象在环境中浮动,这是我不希望的(我相信我试图实现的被称为规范化)。
因此,据我所知,唯一的答案是有一个额外的映射,它充当一个内部人员,我可以检查它以查看数据对象是否仍在内存中:
ConcurrentMap<String, MyObject> interner = new MapMaker()
.weakValues()
.makeMap();
并且将修改加载函数:
Function<String, MyObject> loadFunction = new Function<String, MyObject>() {
@Override
public MyObject apply(String uidKey) {
MyObject dataObject = interner.get(uidKey);
if (dataObject == null) {
dataObject = getFromDataBase(uidKey);
interner.put(uidKey, dataObject);
}
return dataObject;
}
};
但是,对缓存使用两个映射而不是一个映射似乎效率低下。有没有更复杂的方法来解决这个问题?一般来说,我是以正确的方式这样做,还是应该重新考虑我的缓存策略?