问题描述
我使用Map容器??作为LoadingCache中的值:
@Service
public class SlideCacheSpace {
@Value("${value}")
private int expire;
private LoadingCache<Integer, ConcurrentHashMap<Point, Boolean>> loadingCache = CacheBuilder.newBuilder()
.maximumSize(10000)
.expireAfterWrite(expire, TimeUnit.SECONDS)
.build(
new CacheLoader<Integer, ConcurrentHashMap<Point, Boolean>>() {
public ConcurrentHashMap<Point, Boolean> load(Integer key) {
return new ConcurrentHashMap<>(5000);
}
});
public boolean contains(int slug, Point point) {
ConcurrentHashMap<Point, Boolean> points = loadingCache.getIfPresent(slug);
if (points == null) {
return false;
}
return points.contains(point);
}
public void put(int slug, Point point) throws ExecutionException {
ConcurrentHashMap<Point, Boolean> points = loadingCache.get(slug);
points.put(point, true);
}
public void delete(int slug) {
loadingCache.invalidate(slug);
}
}
问题是我的slideCacheSpace.put(key, val)
方法对LoadingCache无效。
调用它之后,LoadingCache不会加载任何内容,并且仍然为空(调试期间检查大小)。
无论put方法被调用多少次,它都保持为空。
但是,每次返回新的Map容器??时,都会调用CacheLoader中的load方法。
看来,LoadingCache只是忽略了它加载的值。
contains
方法从不返回true。
我想知道怎么回事。
1楼
contains方法从不返回true,这是因为Point类未正确实现hashCode / equals方法。 或者,您可以尝试使用String代替Point,那么contains将返回true。
2楼
原因不是很明显。
我在类加载时构建了laodingCache,并且值注入尚未完成。
因此, expire
值始终为0。简单的解决方法:
@Value("${value}")
private int expire;
private LoadingCache<Integer, ConcurrentHashMap<Point, Boolean>> loadingCache;
@PostConstruct
public void init() {
loadingCache = CacheBuilder.newBuilder()
.maximumSize(5000)
.expireAfterAccess(expire, TimeUnit.SECONDS)
.build(new CacheLoader<Integer, ConcurrentHashMap<Point, Boolean>>() {
@Override
public ConcurrentHashMap<Point, Boolean> load(Integer key) {
return new ConcurrentHashMap<>(2500);
}
});
}
价值注入应该按预期方式工作。