![](https://img-blog.csdnimg.cn/20201014180756925.png?x-oss-process=image/resize,m_fixed,h_64,w_64)
caffeine
tydhot
gogogo
展开
-
caffeine 读操作源码走读 为什么读这么快
Caffeine通过get()方法获取缓存中的数据。 Node<K, V> node = data.get(nodeFactory.newLookupKey(key)); if (node == null) { if (recordStats) { statsCounter().recordMisses(1); } return null; } long now = expirationTicker().read(); if (hasExpired(node, now))原创 2020-05-30 16:59:21 · 1035 阅读 · 1 评论 -
caffeine 弱引用key的实现
Caffeine底层的存储容器还是ConcurrentHashMap,如果需要存储的key是一个弱引用,如果直接把key存储到ConcurrentHashMap中时 ,将无可避免的导致一个强引用出现,导致弱引用key的目的失败。 当在构造caffeine的时候如果选择了弱引用的key,最后保存到ConcurrentHashMap中的key将不再是put()时候的key,而是一个封装的弱引用对象WeakReference,保证map中对key的强引用实际指向的是封装的对象引用,缓存中真正指向key的还是一个原创 2020-05-29 00:05:00 · 1447 阅读 · 1 评论 -
caffeine 线程私有的ReadBuffer实现
Caffeine中,读操作后的afterRead操作都会异步操作,不会阻塞到正常的读取操作。 在高并发读取的前提下,为每个读取操作的线程建立了专属的buffer来存放afterRead事件由消费者统一处理afterRead事件,避免高并发读取下对于事件写入buffer的时候的资源竞争。 transient volatile Buffer<E>[] table; StrippedBuffer中维护了一个Buffer[]数组table,用来存放各个线程专属的buffer。 如何界定某.原创 2020-05-25 00:07:03 · 591 阅读 · 0 评论 -
caffeine 时间轮的实现
Caffeine内部实现了一个时间轮。 时间轮的具体实现为一个二维数组,其数组的具体位置存放的则为一个待执行节点的链表。 时间轮的二维数组的第一个维度则是具体的时间间隔,分别是秒,分钟,小时,天,4天,但但并没有严格按照时间单位来区分单位,而是根据以上单位最接近的2的整数次幂作为时间间隔,因此在其第一个维度的时间间隔分别是1.07s,1.14m,1.22h,1.63d,6.5d。 static final long[] SPANS = { ceilingPowerOfTwo(TimeUnit原创 2020-05-18 01:10:54 · 1349 阅读 · 1 评论 -
caffeine 淘汰策略
Caffeine在开启了淘汰策略的时候,维护了三条队列,分别是eden,protected,probation队列。具体的三条队列大小分配方案如下所示, long max = Math.min(maximum, MAXIMUM_CAPACITY); long eden = max - (long) (max * PERCENT_MAIN); long mainProtected = (long) ((max - eden) * PERCENT_MAIN_PROTECTED); 其中,eden为总大小的原创 2020-05-10 23:08:13 · 4342 阅读 · 0 评论 -
caffeine 4hash lfu频度记录
在caffeine中的lfu通过一个long array来记录各个数据的被访问次数,每个被访问到的元素都将被通过4次不同的hash seed来计算位置,分别记录四次,以便达到最小的hash冲突可能性。 因此,long array的每个槽位中的64位空间,出于频度记录需要与空间的平衡,64位被分为4个16位的空间,而16位的空间又将都将被分为4个4位空间区域分别记录4个hash seed的结果。 ...原创 2020-05-05 00:58:47 · 391 阅读 · 0 评论