Guava教程-Cache讲解

概述

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

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.guavagroupId>
  <artifactId>guavaartifactId>
  <version>18.0version>
dependency>

Cache API

一、创建

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

  • CacheLoader
  • Callable

1、通过CacheLoader

LoadingCache graphs = CacheBuilder.newBuilder()
       .maximumSize(1000)
       .expireAfterWrite(10, TimeUnit.MINUTES)
       .build(
           new CacheLoader() {
             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 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() {
    @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 graphs = CacheBuilder.newBuilder()
       .maximumSize(1000)
       .build(
           new CacheLoader() {
             public Graph load(Key key) throws AnyException {
               return createExpensiveGraph(key);
             }
           });

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

LoadingCache graphs = CacheBuilder.newBuilder()
       .maximumWeight(100000)
       .weigher(new Weigher() {
          public int weigh(Key k, Graph g) {
            return g.vertices().size();
          }
        })
       .build(
           new CacheLoader() {
             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 graphs = CacheBuilder.newBuilder()
       .expireAfterAccess(10, TimeUnit.MINUTES)
       .build(
           new CacheLoader() {
             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 Guide:https://github.com/google/guava/wiki
http://ifeve.com/google-guava-cachesexplained/

你可能感兴趣的:(Dubbo)