Guava Cache local cache

About Guava

Guava is an open source based Java library that contains many of the core libraries that Google is using by many of their projects.

This library is for ease of coding and to reduce coding errors.

This library provides utility methods for collections, caching, support primitives, concurrency, common annotations, string handling, I/O and validation .

Guava Cache Applicable Scenarios

1 consumes some memory space to improve speed;

2 The total amount of data stored in the cache will not exceed the memory capacity.

(Guava Cache is a local cache when a single application is running, and does not store data to files or external servers (Memcached, Redis))

Description of Guava Cache

数据结构:ConcurrentHash (The returned cache is implemented as a hash table with similar performance characteristics to ConcurrentHashMap.)

Main features (see related links below for details):

    1 Autoload

    2 Recycling strategy:

        2.1 Based on capacity

        2.2 Based on time-to-live

        2.3 Weight-based

        2.4 Reference-based

    3 Remove the listener

    4 Cache access statistics

Main interface: CacheBuilder, LoadingCache, CacheStats

Example of use:

public class CacheProTest {
    LoadingCache<Long, Person> cache;
    private int cacheTimeoutSeconds = 10; // 10秒

    Integer counter = 1;

    @Before
    public void initialize() {
        System.out.println("initialization");

        cache = CacheBuilder.newBuilder()
                        /* Recovery strategy: based on capacity (least-recently-used eviction when a maximum size is exceeded) */
                        .maximumSize(10)
                        // .initialCapacity(initialCapacity)
                        
                        /* Recycling strategy: time-based expiration of entries, measured since last access or last write */
                        .expireAfterWrite(cacheTimeoutSeconds, TimeUnit.SECONDS)
                        // .expireAfterAccess(duration, unit)
                        // .refreshAfterWrite(duration, unit)
                        
                        /* Recycling strategy: based on weight */
                        // .maximumWeight(maximumWeight)
                        // .weigher(weigher)

                        /* Recycling strategy: based on references (keys automatically wrapped in weak references, values ​​automatically wrapped in weak or soft references)*/
                        // .weakKeys()
                        // .weakValues()
                        // .softValues ​​()
                        
                        // Set the number of concurrency to 5, that is, at most 5 threads can perform write operations to the cache at the same time
                        // .concurrencyLevel(concurrencyLevel)

                        /* accumulation of cache access statistics */
                        .recordStats()
                        
                        /* remove the listener (notification of evicted (or otherwise removed) entries) */
                        // .removalListener(listener)

                        .build(new CacheLoader<Long, Person>() {

                            /* automatic loading of entries into the cache */
                            @Override
                            public Person load(Long id) throws Exception {
                                System.out.println("Get value, id=" + id);

                                // Call the interface to get the value
                                Person p = new Person();
                                p.setId(id);
                                p.setName("name" + counter.toString());
                                counter++;

                                return p;
                            }
                        });
    }

    @Test
    public void test1() {
        try {
            /* get the value */
            // ConcurrentMap<Long, Person> asMap = cache.asMap();

            // cache.get(key); //
            // cache.getAll(keys);

            // cache.getIfPresent(key);
            // cache.getAllPresent (keys);

            // cache.size();

            /* store value */
            // cache.put(key, value);
            // cache.putAll(m); // Map<? extends K, ? extends V> m

            /* remove/delete */
            // cache.refresh(key);
            // cache.invalidate(key);
            // cache.invalidateAll();
            // cache.invalidateAll(keys);
            // cache.cleanUp();

            /* Cache access statistics */
            CacheStats stats = cache.stats();
            stats.averageLoadPenalty();
            stats.evictionCount();
            stats.hitCount();
            stats.hitRate();
            stats.loadCount();
            stats.loadExceptionCount();
            stats.loadExceptionRate();
            stats.loadSuccessCount();
            stats.missCount();
            stats.missRate();
            stats.requestCount();
            stats.totalLoadTime();
        } catch (Exception e) {
            e.printStackTrace ();
        }
    }


    @Test
    public void test2() {
        try {
            Long id = 1L;
            Person person1 = cache.get(id);

            Thread.sleep(3L * 1000L);
            Person person2 = cache.get(id);

            Thread.sleep(11L * 1000L);
            Person person3 = cache.get(id);

            System.out.println(person1);
            System.out.println(person2);
            System.out.println(person3);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

class Person implements Serializable {
    private static final long serialVersionUID = 1L;

    private Long id;

    private String name;

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        return JSON.toJSONString(this);
    }
}

  

Points to pay attention to when using Guava Cache

1 了解LoadingCache.refresh

As LoadingCache.refresh(K) declares, a refresh means loading new values ​​for a key, and this process can be asynchronous .

While a flush operation is in progress, the cache can still return the old value to other threads, unlike a recycle operation where the thread reading the cache must wait for the new value to be loaded.

If the flushing process throws an exception, the cache will keep the old value , and the exception will be discarded after logging [swallowed].

Overriding CacheLoader.reload(K, V) can extend the refresh behavior , this method allows developers to use the old value when calculating the new value.

 

2 Know when to clean up

Caches built with CacheBuilder do not "automatically" perform cleanup and reclamation , nor do they clean up as soon as a cache item expires, and there is no such cleanup mechanism.

It will do a small amount of maintenance incidentally on writes, or occasionally on reads if there are too few writes.

So use LoadingCache.size() must pay attention to this point.

 

Related Links

github address

Yibao Tutorial: Guava Tutorial

CSDN: Introduction to GuavaCache

Concurrent Programming Net: [Google Guava] 3 - Cache

 

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325458523&siteId=291194637
Recommended