一、前言
通过googlecode源码concurrentlinkedhashmap-lru-1.4.2.jar包中的com.googlecode.concurrentlinkedhashmap.ConcurrentLinkedHashMap定义GoogleConcurrentLruCache类实现LRU cache缓存策略,详情代码示例部分。
二、代码示例
import java.util.Set;@b@import java.util.concurrent.atomic.AtomicLong;@b@@b@import com.googlecode.concurrentlinkedhashmap.ConcurrentLinkedHashMap;@b@import com.googlecode.concurrentlinkedhashmap.EvictionListener;@b@import com.googlecode.concurrentlinkedhashmap.Weighers;@b@@b@/**@b@ * 基于google concurrent的LinkedHashMap实现LRU @b@ */@b@public class GoogleConcurrentLruCache<K, V> {@b@@b@ private ConcurrentLinkedHashMap<K, V> cache;@b@ private static final int DEFAULT_CAPACITY = 389;@b@ public static final int DEFAULT_CONCURENCY_LEVEL = 64;@b@ private AtomicLong get = new AtomicLong(0);@b@ private AtomicLong hit = new AtomicLong(0);@b@@b@ public GoogleConcurrentLruCache(){@b@ this(DEFAULT_CAPACITY);@b@ }@b@@b@ public GoogleConcurrentLruCache(int capacity){@b@ if (capacity <= 0) {@b@ capacity = DEFAULT_CAPACITY;@b@ }@b@@b@ cache = new ConcurrentLinkedHashMap.Builder<K, V>().maximumWeightedCapacity(capacity)@b@ .weigher(Weighers.singleton())@b@ .concurrencyLevel(DEFAULT_CONCURENCY_LEVEL)@b@ .build();@b@ }@b@@b@ public GoogleConcurrentLruCache(int capacity, EvictionListener<K, V> listener){@b@ if (capacity <= 0) {@b@ capacity = DEFAULT_CAPACITY;@b@ }@b@@b@ cache = new ConcurrentLinkedHashMap.Builder<K, V>().maximumWeightedCapacity(capacity)@b@ .weigher(Weighers.singleton())@b@ .concurrencyLevel(DEFAULT_CONCURENCY_LEVEL)@b@ .listener(listener)@b@ .build();@b@ }@b@@b@ public long capacity() {@b@ return cache.capacity();@b@ }@b@@b@ public boolean isEmpty() {@b@ return cache.isEmpty();@b@ }@b@@b@ public int size() {@b@ return cache.size();@b@ }@b@@b@ public void clear() {@b@ cache.clear();@b@ }@b@@b@ public V get(Object key) {@b@ V v = cache.get(key);@b@ get.addAndGet(1);@b@ if (v != null) {@b@ hit.addAndGet(1);@b@ }@b@@b@ return v;@b@ }@b@@b@ public void put(K key, V value) {@b@ cache.put(key, value);@b@ }@b@@b@ public boolean putIfAbsent(K key, V value) {@b@ return cache.putIfAbsent(key, value) == null;@b@ }@b@@b@ public boolean replace(K key, V old, V value) {@b@ return cache.replace(key, old, value);@b@ }@b@@b@ public void remove(K key) {@b@ cache.remove(key);@b@ }@b@@b@ public Set<K> keySet() {@b@ return cache.keySet();@b@ }@b@@b@ public Set<K> hotKeySet(int n) {@b@ return cache.descendingKeySetWithLimit(n);@b@ }@b@@b@ public boolean containsKey(K key) {@b@ return cache.containsKey(key);@b@ }@b@@b@ public String getStatus() {@b@ StringBuilder sb = new StringBuilder();@b@ sb.append("current size:");@b@ sb.append(cache.size());@b@ sb.append(" get:");@b@ sb.append(get);@b@ sb.append(" hit:");@b@ sb.append(hit);@b@ sb.append(" hit ratio:");@b@ if (get.longValue() > 0) {@b@ sb.append((hit.doubleValue() / get.doubleValue()) * 100);@b@ sb.append("%");@b@ } else {@b@ sb.append("--");@b@ }@b@@b@ get.set(0);@b@ hit.set(0);@b@@b@ return sb.toString();@b@ }@b@}