LRU,即Least Recently Used,最近最少使用的缓存将最先被淘汰
ConcurrentLRUCache中使用ConcurrentHashMap来存储缓存(k-v),
这样能保证其线程安全。
存储的value有一个时间戳(不是真的时间戳,而是cache内维护的一个全局自增字段)来存储它的最近更新时间。
当缓存数到达upperSize(具体指什么,范围?)时将触发缓存的淘汰机制。
这个淘汰过程是并发的,类似于cms的回收过程。这个过程会分几个阶段并发扫描ConcurrentHashMap。
第一批淘汰时会计算出最小的时间戳minV,当前时间戳nextV,和需要移除的数量numToReomve(这个值等于当前size减去最小容量)。minV是变化的,在遍历过程中会变化。当一个缓存的时间戳v大于nextV - 最小容量则保留,若v小于minV +numToRemove则移除,否则会被加入一个数组elist,为之后的淘汰做准备。
通过第一批淘汰,显然淘汰的缓存数可能小于需要淘汰数,因此在判断淘汰任务未达标之后,便执行下一轮的淘汰。
第二批淘汰,对elist的缓存做第一批淘汰的操作。
同样检测是否淘汰达标,若没有达标则进行第三波操作
第三批淘汰,直接使用优先队列(堆)淘汰最小的numToRemove个缓存。由于之前的淘汰是根据minV来决定的,而minV是浮动的,所以淘汰数不准确,而直接使用堆则可以稳定淘汰numToRemove个,当然需要付出更多的时间.
以上是ConcurrentLRUCache的部分实现,可见和cms的gc过程十分相似,分很多波来进行标记和删除,可见在并发环境下,多部的,不稳定的操作是高效的。
网友评论