本文基于的guava版本是19.0
使用guava cache的时候,在cache中没有值或者值需要更新的时候,都需要去load,而这个load往往对应从数据库或者远程接口拿数据并缓存下来的操作。在高qps场景的服务中,这个load可能会导致调用链的阻塞,如果阻塞时间长,可能会影响服务,甚至可能拖垮服务,所以要了解哪些地方会阻塞,有没有什么方法能够尽量少的去阻塞。
一.同步load
1.load
load是第一次加载,加载之前cache中没有值。load永远都是同步的,不管是否使用异步进行包装,具体见下面第三部分。
对于同一个key,多次请求只会触发一次加载。比如,线程1访问key1,发现cache中不存在key1,然后触发key1的load。与此同时,在load加载完成之前,线程2,线程3...线程N都访问key1,这些访问不会再触发key1的加载,但是在key1的load加载完成之前,这些请求都会被hang在那里等待。调用链如下:
get:4952, LocalCache$LocalLoadingCache
getOrLoad:3967, LocalCache
get:3963, LocalCache
get:2046, LocalCache$Segment
lockedGetOrLoad:2140, LocalCache$Segment
waitForLoadingValue:2153, LocalCache$Segment
waitForValue:3571, LocalCache$LoadingValueReference
getUninterruptibly:168, Uninterruptibles->这里用future的get方法阻塞在这里,直到第一个触发load操作的线程完成load操作并将结果设置到该future中,这个get方法就会解除阻塞并获取到load到的值。
2.reload
reload是之前cache中有值,需要刷新该值,比如设置了过期时间后,到了缓存过期需要更新的时间,会触


9262

被折叠的 条评论
为什么被折叠?



