我在wiki 页面中阅读了有关缓存的代码示例/文档。我看到回调RemovalListener
可用于拆除被驱逐的缓存对象等。我的问题是在调用提供的RemovalListener
. 让我们考虑文档中的代码示例:
CacheLoader<Key, DatabaseConnection> loader =
new CacheLoader<Key, DatabaseConnection> () {
public DatabaseConnection load(Key key) throws Exception {
return openConnection(key);
}
};
RemovalListener<Key, DatabaseConnection> removalListener =
new RemovalListener<Key, DatabaseConnection>() {
public void onRemoval(RemovalNotification<Key, DatabaseConnection> removal) {
DatabaseConnection conn = removal.getValue();
conn.close(); // tear down properly
}
};
return CacheBuilder.newBuilder()
.expireAfterWrite(2, TimeUnit.MINUTES)
.removalListener(removalListener)
.build(loader);
这里的缓存被配置为在创建后 2 分钟驱逐元素(我知道它可能不是精确的两分钟,因为驱逐将与用户读/写调用等一起被捎带。)但无论是什么时候,图书馆都会检查那里传递给的对象是否没有活动引用RemovalListener
?因为我可能有另一个线程很早就从缓存中获取了对象,但可能仍在使用它。在那种情况下,我不能close()
从 RemovalListener 调用它。
的文档RemovalNotification
还说:删除单个条目的通知。如果它们已经被垃圾回收,则键和/或值可能为空。
所以根据它conn
可能是null
在上面的例子中。在这种情况下,我们如何正确地拆除 conn 对象?在这种情况下,上面的代码示例也会抛出NullPointerException
.
我试图解决的用例是:
- 缓存元素需要在创建两分钟后过期。
- 被驱逐的对象需要是
closed
,但只有在确保没有人使用它们之后。