google的guava可谓鼎鼎有名,最近在研究缓存,也就看看它是怎么处理缓存过期问题的;首先它并没有通过在后台起一个线程,不停去轮询。不这么做主要是为了效率吧,也就是所谓的惰性移除,在get时判断是否过期。那如果一直不访问,可能存在内存泄漏问题。

示例代码:

 Cache<Object, Object> cache = CacheBuilder.newBuilder().expireAfterAccess(2,TimeUnit.SECONDS).build();
        cache.put("a",1);
        System.out.println(cache.getIfPresent("a"));

        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        System.out.println(cache.getIfPresent("a"));

1,CacheBuilder默认的缓存实现为LocalCache,所以这里我们主要去研究LocalCache的getIfPresent 即可

2,通过观察,我们可以猜出LocalCache 是用类似于ConcurrentHashMap 的数据结构来保存数据的

3,这里我们主要看其Segment 的get 方法,然后进入getLiveEntry 方法,看名字感觉跟存活有关,点进去

    ReferenceEntry<K, V> getLiveEntry(Object key, int hash, long now) {
//获取值
      ReferenceEntry<K, V> e = getEntry(key, hash);
      if (e == null) {//如果为空,返回空
        return null;
      } else if (map.isExpired(e, now)) {//判断是否过期
        tryExpireEntries(now);
        return null;
      }
      return e;
    }


boolean isExpired(ReferenceEntry<K, V> entry, long now) {
    checkNotNull(entry);
    if (expiresAfterAccess() && (now - entry.getAccessTime() >= expireAfterAccessNanos)) {
      return true;
    }
    if (expiresAfterWrite() && (now - entry.getWriteTime() >= expireAfterWriteNanos)) {
      return true;
    }
    return false;
  }
03-01 05:17