簡體   English   中英

重新加載同時具有並發讀取器的多個緩存

[英]reload multiple caches which have concurrent readers simultaneously

我使用多個哈希映射將參考數據存儲在一個類中

Map map1;
Map map2;
Map map3;

它們由多個讀者同時訪問。 我想同時重新初始化它們。 如果它是一張地圖,我可以做

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

由於現有讀者擁有舊參考,而新讀者獲得新參考,因此工作正常。 但是由於我有多個地圖,新讀者可能會得到最新版本的map1map2而舊版本的map3 ,因為替換操作不是原子的。

好的,所以我需要鎖定它,這讓我想到了我的問題。 除了使用synchronized鎖定所有內容之外,還有什么優雅的方法可以做到這一點?

我只需要在重新加載實際發生時鎖定,而不是其他時候。 我查看了 java locks(Read write), Conditions, CyclicBarriers, Countdownlatches等,但不確定什么是正確的方法。

如果您創建新地圖,那么讀者無論如何都需要有一種方法來獲取新地圖的參考。 因此,不要直接引用 mapX,而是保留對包含所有地圖的對象的引用。 當您只分配新對象的引用時,就可以原子地替換它,就像您在示例中所做的那樣。 您將在每個地方都擁有 holder.map1,而不是使用 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
    }
}

由於您想同時使所有緩存無效,您可以

  • 像你說的那樣用同步來阻止一切
  • 使用標志將它們設置為“無效”並禁止讀取器訪問,直到它們全部重新加載。 如果緩存重新加載很昂貴,您可以為每個緩存設置一個標志,以指示哪個緩存無效。 這真的取決於你的應用程序

最優雅的選擇是使用准備好的東西,比如spring 緩存(如果你使用的是 spring),它還管理分布式緩存

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM