2014-05-12 64 views
0

我正在創建自己的緩存對象,它將服務於多個線程,這是一個任務,因此我不允許使用包和jar。我想弄清楚如何在同一時間使所有人無效。 我有一個日期結構,其中包含一堆條目,其中鍵是一個整數,值是一個布爾值。當工作人員遺漏時,它會將值添加到其緩存中。 我有其他幾個線程更新這個數據結構,並且一旦他們更新它們,它們應該使擁有這個緩存的所有其他工作線程無效,只有當這個條目在它們的緩存中。同時使Java中的幾個工人的緩存無效而不損害性能

例如 說,有兩名工人 T1緩存有1,真 T2緩存具有3,真

和數據結構具有如圖1所示,真實的; 2,真實的; 3是真的。現在更新程序更改3,爲false。所以它應該檢查T1並且不做任何事情,並且應該檢查T2並且改變它。但是,這兩個檢查應該以某種方式同時發生,因爲如果我有一個T1高速緩存有3個的情況,則爲真 T2高速緩存有3個,真 T1可能失效,而T2尚未失效,而我們有不一致的行爲。

什麼想法? 我的緩存代碼

import java.util.LinkedHashMap; 
import java.util.Map; 
import java.util.concurrent.locks.ReentrantLock; 

public class workerCache { 
    @SuppressWarnings("rawtypes") 
    LinkedHashMap cache; 
    ReentrantLock lock; 

    @SuppressWarnings("serial") 
    public <T> workerCache(final int maxEntries) { 
     this.lock = new ReentrantLock(); 

     this.cache = new LinkedHashMap<T, T>(maxEntries + 1) { 
      @SuppressWarnings("rawtypes") 
      protected boolean removeEldestEntry(Map.Entry eldest) { 
       return size() > maxEntries; 
      } 
     }; 
    } 

    @SuppressWarnings("unchecked") 
    public <T> void setEntry(T key, T value) { 

     lock.lock(); 
     try { 
      cache.put(key, value); 
     } finally { 
      lock.unlock(); 
     } 
    } 

    public <T> void invalidateEntry(T key) { 
     lock.lock(); 
     try { 
      cache.remove(key); 
     } finally { 
      lock.unlock(); 
     } 

    } 

    @SuppressWarnings("unchecked") 
    public <T> T get(T key) { 
     lock.lock(); 
     try { 
      return (T) this.cache.get(key); 
     } finally { 
      lock.unlock(); 
     } 
    } 
+0

您的緩存體系結構排除了除您的要求的全局鎖定之外的任何內容。重新設計緩存,並且當您處理緩存時,請關閉當前緩存API引入的可能的完整性差距(如果get()返回值的瞬間該值發生更改,會發生什麼情況?)。 – Durandal

+0

這是問題,如何在更改後使所有數據無效?否則,我發現自己的情況,你剛剛描述 – Quantico

+0

考慮責任倒置:而不是updater通知緩存,讓緩存驗證其條目是有效的每個get()。還要仔細考慮工作人員和緩存之間的可恢復性 - 誰負責處理緩存未命中?誰控制條目的完整性?誰控制數據的完整性*衍生*條目(即結果)? – Durandal

回答

1

這聽起來像你想象三個線程「T1」,「T2」,「T3」都有自己的workerCache,他們需要保持同步副本。這是正確的嗎?

如果是這樣,我會說這是一個問題。而不是三個緩存(每個線程一個緩存),所有線程之間如何共享一個緩存?

這樣,每個人都看到相同的數據b/c只有一個數據副本(因爲只有一個緩存)。如果您從T1中取消條目,則每個人都會同時「看到」該失效 - 這是因爲只有一個緩存。

如果您有三個線程全部更新相同的密鑰,那麼最後一個進入緩存將勝出。我不確定這是否是您的問題。

我在哪裏接近問題?

+0

這是一個有趣的解決方案。但是,這不是降低緩存的有效性嗎?如同使用3個線程共享這個對象,將導致線程去往內存中的某個位置來訪問它,而不是擁有本地副本。也許我沒有得到記憶和地方的所有想法。 – Quantico

+1

當您有多個作家競爭相同的緩存行時,內存局部性是一個問題。如果你有多個閱讀器,那麼他們可以擁有自己的處理器本地拷貝,這是處理器緩存和緩存失效工作的副作用。 (我的意思是在覈心和襪子之間執行緩存失效以及硬件等)。 請參閱http://mechanical-sympathy.blogspot.com/2011/09/single-writer-principle.html進行討論,esp 「規模原則」 –

相關問題