2016-02-04 24 views
2

我必須存儲在使用多個哈希類引用的數據映射重裝具有併發讀者同時

Map map1; 
Map map2; 
Map map3; 

它們是由多個讀者同時訪問多個緩存。我想在同一時間重新初始化它們。 如果它是一個單一的地圖,我只是做

public void reload(){ 
    map1 = createNewMapWithLatestData(); 
} 

由於現有的讀者都有老的參考和新的讀者得到它正常工作了新的參考。但是由於我有多個地圖,新讀者可能會得到最新版本的說明map1map2,但是舊版本map3,因爲替換操作不是原子的。

好的,所以我需要鎖定它,這使我想到了我的問題。除了使用​​鎖定所有內容之外,使用這種方法的優雅方式是什麼?

我只需要一個鎖,當重新加載實際發生時,而不是其他時間。 我看着java locks(Read write), Conditions, CyclicBarriers, Countdownlatches等,但不知道什麼是正確的方法。

回答

1

如果您創建新地圖,那麼讀者將需要有辦法獲得新地圖的參考。因此,不要直接引用mapX,而要保存對保存所有映射的對象的引用。這可以被原子替換,因爲您只需分配新對象的引用,就像您在示例中所做的那樣。不是使用map1,而是在每個地方都有holder.map1。

class Holder { 
    Map map1; 
    Map map2; 
} 

class Reader { 
    Holder holder; 
    void read() { 
     writer.getHolder().map1.get("x"); 
    } 
} 

class Writer { 
    Holder holder; 
    Holder getHolder() { 
     return holder; 
    } 
    void reload() { 
     Holder newHolder = new Holder(); 
     newHolder.map1 = createNewMap1WithLatestData(); 
     newHolder.map2 = createNewMap2WithLatestData(); 
     holder = newHolder; // this is atomic 
    } 
} 
+0

一切軟件可以用1級來解決重新定向/抽象......我再次學習它! – Abe

+0

誰拒絕地圖的其他貢獻者保存某處引用「持有人」的地圖? – Andremoniy

+0

@你應該知道,這隻會讓你的問題更加深入,就像手指上的碎片一樣。 – Andremoniy

0

您提供的代碼非常少,所以答案會很相似。是的,你需要ReadWriteLock。請閱讀關於它的教程。簡而言之,你總是允許閱讀地圖(讀鎖)。但是當你想同步它們的初始化時,你「打開」寫入鎖定,這將鎖定所有可鎖定的塊,並且在初始化它們時不允許讀取或寫入地圖。

1

既然你想所有的緩存,同時失效,你可以

  • 塊都具有syncrhonized如你所說
  • 使用標誌設置這些「無效的」,並禁止閱讀器的訪問權限,直到它們全部重新加載。如果緩存重新加載很昂貴,您可以爲每個緩存設置一個標誌來指示哪個緩存無效。這真的取決於你的應用

最優雅的辦法是使用的東西準備像spring cache(如果使用的是彈簧),它還管理分佈式緩存

相關問題