本文主要研究一下dubbo的LRUCache
dubbo-2.7.2/dubbo-common/src/main/java/org/apache/dubbo/common/utils/LRUCache.java
public class LRUCache<K, V> extends LinkedHashMap<K, V> { private static final long serialVersionUID = -5167631809472116969L; private static final float DEFAULT_LOAD_FACTOR = 0.75f; private static final int DEFAULT_MAX_CAPACITY = 1000; private final Lock lock = new ReentrantLock(); private volatile int maxCapacity; public LRUCache() { this(DEFAULT_MAX_CAPACITY); } public LRUCache(int maxCapacity) { super(16, DEFAULT_LOAD_FACTOR, true); this.maxCapacity = maxCapacity; } @Override protected boolean removeEldestEntry(java.util.Map.Entry<K, V> eldest) { return size() > maxCapacity; } @Override public boolean containsKey(Object key) { lock.lock(); try { return super.containsKey(key); } finally { lock.unlock(); } } @Override public V get(Object key) { lock.lock(); try { return super.get(key); } finally { lock.unlock(); } } @Override public V put(K key, V value) { lock.lock(); try { return super.put(key, value); } finally { lock.unlock(); } } @Override public V remove(Object key) { lock.lock(); try { return super.remove(key); } finally { lock.unlock(); } } @Override public int size() { lock.lock(); try { return super.size(); } finally { lock.unlock(); } } @Override public void clear() { lock.lock(); try { super.clear(); } finally { lock.unlock(); } } public int getMaxCapacity() { return maxCapacity; } public void setMaxCapacity(int maxCapacity) { this.maxCapacity = maxCapacity; } }
dubbo-2.7.2/dubbo-common/src/test/java/org/apache/dubbo/common/utils/LRUCacheTest.java
public class LRUCacheTest { @Test public void testCache() throws Exception { LRUCache<String, Integer> cache = new LRUCache<String, Integer>(3); cache.put("one", 1); cache.put("two", 2); cache.put("three", 3); assertThat(cache.get("one"), equalTo(1)); assertThat(cache.get("two"), equalTo(2)); assertThat(cache.get("three"), equalTo(3)); assertThat(cache.size(), equalTo(3)); cache.put("four", 4); assertThat(cache.size(), equalTo(3)); assertFalse(cache.containsKey("one")); assertTrue(cache.containsKey("two")); assertTrue(cache.containsKey("three")); assertTrue(cache.containsKey("four")); cache.remove("four"); assertThat(cache.size(), equalTo(2)); cache.put("five", 5); assertFalse(cache.containsKey("four")); assertTrue(cache.containsKey("five")); assertTrue(cache.containsKey("two")); assertTrue(cache.containsKey("three")); assertThat(cache.size(), equalTo(3)); } @Test public void testCapacity() throws Exception { LRUCache<String, Integer> cache = new LRUCache<String, Integer>(); assertThat(cache.getMaxCapacity(), equalTo(1000)); cache.setMaxCapacity(10); assertThat(cache.getMaxCapacity(), equalTo(10)); } }
LRUCache继承了LinkedHashMap,其initialCapacity为16,maxCapacity默认是1000;它覆盖了removeEldestEntry方法,当size()大于maxCapacity时返回true;它还声明了一个ReentrantLock,对containsKey、get、put、remove、size、clear方法进行了加锁操作