Guava教程-Cache讲解

本文介绍了Guava缓存的基本概念及其实战应用。通过详细解释CacheLoader和Callable两种创建方式,以及如何进行缓存的插入、清除和删除操作,帮助读者深入理解Guava缓存的工作原理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

概述

缓存是日常开发中经常应用到的一种技术手段,合理的利用缓存可以极大的改善应用程序的性能。

Guava官方对Cache的描述

Caches are tremendously useful in a wide variety of use cases. For example, you should consider using caches when a value is expensive to compute or retrieve, and you will need its value on a certain input more than once.

A Cache is similar to ConcurrentMap, but not quite the same. The most fundamental difference is that a ConcurrentMap persists all elements that are added to it until they are explicitly removed. A Cache on the other hand is generally configured to evict entries automatically, in order to constrain its memory footprint. In some cases a LoadingCache can be useful even if it doesn’t evict entries, due to its automatic cache loading.

适用场景

  • You are willing to spend some memory to improve speed.
  • You expect that keys will sometimes get queried more than once.
  • Your cache will not need to store more data than what would fit inRAM. (Guava caches are local to a single run of your application.
    They do not store data in files, or on outside servers. If this does
    not fit your needs, consider a tool like Memcached.)

实战

maven依赖

<dependency>
  <groupId>com.google.guava</groupId>
  <artifactId>guava</artifactId>
  <version>18.0</version>
</dependency>

Cache API

一、创建

Guava Cache有以下两种创建方式:

  • CacheLoader
  • Callable
1、通过CacheLoader
LoadingCache<Key, Graph> graphs = CacheBuilder.newBuilder()
       .maximumSize(1000)
       .expireAfterWrite(10, TimeUnit.MINUTES)
       .build(
           new CacheLoader<Key, Graph>() {
             public Graph load(Key key) throws AnyException {
               return createExpensiveGraph(key);
             }
           });

然后,我们可以通过 V LoadingCache.get(K key) 方法来获取cache

try {
  return graphs.get(key);
} catch (ExecutionException e) {
  throw new OtherException(e.getCause());
}

也可以不处理异常

return graphs.getUnchecked(key);
2、通过Callable
Cache<Key, Value> cache = CacheBuilder.newBuilder()
    .maximumSize(1000)
    .build(); 

然后通过Cache.get(String arg0, Callable

try {
  // If the key wasn't in the "easy to compute" group, we need to
  // do things the hard way.
  cache.get(key, new Callable<Value>() {
    @Override
    public Value call() throws AnyException {
      return doThingsTheHardWay(key);
    }
  });
} catch (ExecutionException e) {
  throw new OtherException(e.getCause());
}
二、显式插入

使用cache.put(key, value)方法可以直接向缓存中插入值,这会直接覆盖掉给定键之前映射的值。

例如:

cache.put(key, value)
三、清除

1、基于大小
通过CacheBuilder.maximumSize(long)指定缓存容量大小,如下:

LoadingCache<Key, Graph> graphs = CacheBuilder.newBuilder()
       .maximumSize(1000)
       .build(
           new CacheLoader<Key, Graph>() {
             public Graph load(Key key) throws AnyException {
               return createExpensiveGraph(key);
             }
           });

另外,如果缓存值占据完全不同的内存空间,可以使用CacheBuilder.maximumWeight(long)指定最大总重,如下:

LoadingCache<Key, Graph> graphs = CacheBuilder.newBuilder()
       .maximumWeight(100000)
       .weigher(new Weigher<Key, Graph>() {
          public int weigh(Key k, Graph g) {
            return g.vertices().size();
          }
        })
       .build(
           new CacheLoader<Key, Graph>() {
             public Graph load(Key key) { // no checked exception
               return createExpensiveGraph(key);
             }
           });

2、基于时间
CacheBuilder provides two approaches to timed eviction:

  • expireAfterAccess(long, TimeUnit) Only expire entries after the
    specified duration has passed since the entry was last accessed by a
    read or a write. Note that the order in which entries are evicted
    will be similar to that of size-based eviction.
  • expireAfterWrite(long, TimeUnit) Expire entries after the specified
    duration has passed since the entry was created, or the most recent
    replacement of the value. This could be desirable if cached data
    grows stale after a certain amount of time.

例如:

LoadingCache<Key, Graph> graphs = CacheBuilder.newBuilder()
       .expireAfterAccess(10, TimeUnit.MINUTES)
       .build(
           new CacheLoader<Key, Graph>() {
             public Graph load(Key key) { // no checked exception
               return createExpensiveGraph(key);
             }
           });
四、显示删除

At any time, you may explicitly invalidate cache entries rather than waiting for entries to be evicted. This can be done:

  • individually, using Cache.invalidate(key)
  • in bulk, using Cache.invalidateAll(keys)
  • to all entries, using Cache.invalidateAll()

参考文档

Guava User Guidehttps://github.com/google/guava/wiki
http://ifeve.com/google-guava-cachesexplained/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值