我使用了cache2k,并在web应用程序中进行了通读,以按需加载博客文章。但是,我担心的是阻塞的读取功能。例如,如果多个线程(请求)请求缓存获取相同的密钥,那么是否有可能多次调用Read身方法来将相同的键/值加载到缓存中?
我从文档中得到的印象是,的通读功能会阻止对相同密钥的并发请求,直到加载完成为止,但我可以错误地阅读文档。我只想确认一下这就是行为。
初始化缓存的方法如下所示:
private void initializeURItoPostCache()
{
final CacheLoader<String, PostImpl> postFileLoader = new CacheLoader<String, PostImpl>(){
@Override public PostImpl load(String uri)
{
// Fetch the data and create the post object
final PostImpl post = new PostImpl();
//.. code omitted
return post;
}
};
// Initialize the cache with a read-through loader
this.cacheUriToPost = new Cache2kBuilder<String, PostImpl>(){}
.name("cacheBlogPosts")
.eternal(true)
.loader(postFileLoader)
.build();
}以下方法用于从缓存中请求post:
public Post getPostByURI(final String uri)
{
// Check with the index service to ensure the URI is known (valid to the application)
if(this.indexService.isValidPostURI(uri))
{
// We have a post associated with the given URI, so
// request it from the cache
return this.cacheUriToPost.get(uri);
}
return EMPTY_POST;
}向大家表示感谢,并祝大家新年快乐、繁荣。
发布于 2016-12-31 08:32:42
当对同一键的多个请求将引发缓存加载器调用时,cache2k将只调用加载程序一次。其他线程等待加载完成。这种行为称为阻塞读取。引用“Java文档”中的话:
阻塞:如果加载程序是由
Cache.get(K)或允许透明访问的其他方法调用的,则同一键上的并发请求将被阻塞,直到加载完成为止。对于过期值,可以通过启用Cache2kBuilder.refreshAhead(boolean)来避免阻塞。不能保证每次只为一个键调用加载程序。例如,在调用Cache.clear()之后,一个键的加载操作可能会重叠。
这种行为对于缓存非常重要,因为它可以防止缓存踩踏。例如:高流量网站每秒接收1000个请求。一个资源需要很长时间才能生成,大约100毫秒。当缓存没有阻塞多个请求时,当缓存失败时,至少会有100个请求访问加载程序以获得相同的键。“至少”是一种轻描淡写的说法,因为您的机器可能无法以相同的速度处理100个请求。
请记住,缓存没有硬保证。当同一键同时被调用时,加载程序仍必须能够正确执行。例如,阻塞读取和Cache.clear()导致了相互竞争的需求。Cache.clear()应该是快速的,这意味着我们不希望等待正在进行的加载操作完成。
https://stackoverflow.com/questions/41374834
复制相似问题