看一看Dubbo中實現的LRU快取
阿新 • • 發佈:2020-08-24
最近遇見多次LRUCache,網上看了不少,自己也手寫了一個,最近看Dubbo原始碼也碰到了Dubbo中的LRUCache。
摘出來瞧瞧。
Dubbo的LRUCache位於dubbo-common的 com.alibaba.dubbo.common.utils 包下,跟我自己手寫的LRUCache區別不大,都是繼承了LinkedHashMap來實現,
dubbo的LRUCache重寫了LinkedHashMap的get、put、remove、size、clear和containsKey方法,將這些方法改為執行緒安全的實現,採用ReentrantLock加鎖實現,
ReentrantLock和synchronized一樣,加的是悲觀鎖,底層實現機制不同,synchronized底層依賴JAVA物件的Monitor鎖,ReentrantLock底層是AQS(抽象佇列同步器)。
據說ReentrantLock比synchronized效能要好,不過我也沒驗證過。
package com.alibaba.dubbo.common.utils; import java.util.LinkedHashMap; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; public class LRUCache<K, V> extends LinkedHashMap<K, V> { private static finallong 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) { try { lock.lock(); return super.containsKey(key); } finally { lock.unlock(); } } @Override public V get(Object key) { try { lock.lock(); return super.get(key); } finally { lock.unlock(); } } @Override public V put(K key, V value) { try { lock.lock(); return super.put(key, value); } finally { lock.unlock(); } } @Override public V remove(Object key) { try { lock.lock(); return super.remove(key); } finally { lock.unlock(); } } @Override public int size() { try { lock.lock(); return super.size(); } finally { lock.unlock(); } } @Override public void clear() { try { lock.lock(); super.clear(); } finally { lock.unlock(); } } public int getMaxCapacity() { return maxCapacity; } public void setMaxCapacity(int maxCapacity) { this.maxCapacity = maxCapacity; } }