我正在尝试使用一个番石榴缓存作为ConcurrentLinkedHashMap的替代品。但是我发现,虽然ConcurrentLinkedHashMap允许我按插入顺序遍历映射,但Guava的asMap()方法并不按任何特定顺序返回元素。我是遗漏了什么,还是这个功能根本不可用?
示例(试图打印键、值和条目):
Cache<Integer, Integer> cache = CacheBuilder.newBuilder().maximumSize(10).initialCapacity(10)
.expireAfterAccess(10000, TimeUnit.SECONDS).build();
cache.put(1, 1);
cache.put(2, 2);
cache.put(3, 3);
cache.put(4, 4);
cache.put(5, 5);
cache.put(6, 6);
Iterator<Integer> iter1 = cache.asMap().keySet().iterator();
System.out.println("Keys");
while (iter1.hasNext())
System.out.println(iter1.next());
System.out.println("Values");
Iterator<Integer> iter2 = cache.asMap().values().iterator();
while (iter2.hasNext())
System.out.println(iter2.next());
System.out.println("Entries");
Iterator<Entry<Integer, Integer>> iter3 = cache.asMap().entrySet().iterator();
while (iter3.hasNext()) {
Entry<Integer,Integer> entry = iter3.next();
System.out.println(entry.getKey() + " " + entry.getValue());
}指纹:
Keys
2
6
1
4
3
5
Values
2
6
1
4
3
5
Entries
2 2
6 6
1 1
4 4
3 3
5 5发布于 2018-05-07 18:34:24
CacheWriter将允许在显式写入或删除时调用代码。对于加载缓存,您必须在加载器中执行相同的工作。这也是在条目的锁下执行的,所以您可以假设原子性。这将使您可以在不依赖缓存的内部数据结构的情况下维护排序。注意,如果执行有序迭代时所做的工作很昂贵,您可能希望在锁内复制它,然后在外部执行该工作,以避免阻止缓存写入。
LinkedHashMap<K, V> orderedMap = new LinkedHashMap<>();
LoadingCache<K, V> cache = Caffeine.newBuilder()
.writer(new CacheWriter<K, V>() {
public void write(K key, V value) {
synchronized (orderedMap) {
orderedMap.put(key, value);
}
}
public void delete(K key, V value, RemovalCause cause) {
if (cause == RemovalCause.REPLACED) {
return;
}
synchronized (orderedMap) {
orderedMap.remove(key);
}
}
})
.maximumSize(1_000)
.build(key -> {
V value = ...
synchronized (orderedMap) {
orderedMap.put(key, value);
}
return value;
});
cache.put(key1, value); // calls writer under lock
cache.get(key2); // calls loader under lock; not writer
cache.invalidate(key1); // calls writer under lock
cache.policy().eviction().get().setMaximum(0); // calls writer under lock
synchronized (orderedMap) {
for (K key : orderedMap.keySet()) {
// do work, but blocks writes!
}
}发布于 2014-02-24 09:57:13
(回答我自己的问题)
似乎fge的答案是正确的,番石榴缓存不能按插入顺序迭代。作为解决办法,我使用了前面提到的ConcurrentLinkedHashMap,它的特性不那么丰富,但允许有序的迭代。
我仍然希望得到番石榴团队成员的正式答复,因为这似乎表明ConcurrentLinkedHashMap没有完全集成到番石榴中(与ConcurrentLinkedHashMap文档相反)。
https://stackoverflow.com/questions/21966778
复制相似问题