我有基於ConcurrentHashMap的一個緩存類。該緩存用於存儲從相對較慢的參考數據服務中獲得的結果。這緩存併發查詢
的一個問題是,當多個線程試圖獲取不存在的關鍵,無論是線程會去獲取與基準數據服務相同的密鑰,從而導致兩個參考數據呼叫。
我想,以提高緩存的實施,使只有一個線程查詢引用數據服務。
對此有任何標準的實施?
我有基於ConcurrentHashMap的一個緩存類。該緩存用於存儲從相對較慢的參考數據服務中獲得的結果。這緩存併發查詢
的一個問題是,當多個線程試圖獲取不存在的關鍵,無論是線程會去獲取與基準數據服務相同的密鑰,從而導致兩個參考數據呼叫。
我想,以提高緩存的實施,使只有一個線程查詢引用數據服務。
對此有任何標準的實施?
這裏是存儲在一個列表<>鑰匙鎖的唯一的密鑰,並且如果與所述等效值的對象被傳遞它會返回相同的密鑰對,然後一個synchroized塊上的鍵
private final List<Object> keyLocks = new ArrayList<>(); // field in Cache
public Object get(Object key){
Object lock;
synchronized (keyLocks) {
if (!keyLocks.contains(key)) {
keyLocks.add(key);
lock = key;
} else {
lock = keyLocks.get(keyLocks.indexOf(key));
}
}
synchronized (lock) {
if(innerCache.containsKey(key)){
return cache.get(key);
}else{
Object result = dataService.get(key);
innerCache.put(key,result);
return result;
}
}
}
示例代碼
你假設他們正在使用相同的實際密鑰訪問。如果他們使用兩個相同的密鑰訪問會怎麼樣? – RealSkeptic
是的,這是有問題的,我會更新帖子。 – Zpetkov
谷歌'memoizer ConcurrentHashMap' – ZhongYu
有輕量的高速緩存,例如護目鏡番石榴緩存或[cache2k](http://cache2k.org),它們具有默認所需的行爲。 番石榴,你需要做一個LoadingCache,在cache2k您需要定義一個高速緩存源。 – cruftex