2017-06-15 45 views
0

我有我要讓線程安全以下JedisCluster IMPL -不經常寫和頻繁的讀取

public class Cluster { 
    private List<String> hostPorts; 
    private Map<String, JedisPool> hostPool = 
      new ConcurrentHashMap<String, JedisPool>(); 

    public add(String node) { 
     hostPorts.add(node); 
     hostPool.add(node, create_pool); 
    } 

    public remove(String node) { 
     hostPorts.remove(node); 
     JedisPool pool = hostPool.remove(node) 
     pool.destroy(); 
    } 

    public String getMaster(String key) { 
     return hostPorts.get(some_hash() % hostPool.size()); 
    } 

    public JedisPool getPool(String node) { 
     return redisHostPool.get(node); 
    } 

以下是線程 -

  • 1寫線程將更新狀態時一個節點是 添加/從集羣中刪除 - 這種情況很少發生
  • 1讀線程將頻繁閱讀調用getMaster()和 getPool()。

我想知道使用併發處理上述場景的最佳策略。我想避免在方法級別同步,因爲讀取非常頻繁。

+0

通常,您應該只同步代碼的_critical section_s,即訪問共享數據的最小代碼段。你沒有告訴我們哪些數據是共享的,但我猜'hostPorts'和'hostPool',應該是'final'。如果這是正確的,你的整個'getMaster','getPool'和'add'方法體需要在你使用的任何監視器或鎖上進行同步,並且'remove'方法內的兩個'remove'調用需要處於同步塊一起。 (在你的例子中'add'和'remove'不會編譯。) –

回答

1

使用ReadWriteLock,這通常是指ReentrantReadWriteLock

ReadWriteLock維護一對相關的鎖,一個用於只讀操作,另一個用於寫入的。只要沒有寫入器,讀取鎖可以由多個讀取器線程同時保存。寫鎖定是獨佔的。

+0

即使我使用writeLock裏面的add/remove和readLock裏面的getMaster/getPool,可能會出現以下情況,我無法避免損壞 - 1] reader get master 2] writer刪除節點(與之前讀取的讀者相同)3] reader讀取器調用getPool傳遞在步驟1中獲取的主集合],這將在步驟2中刪除時返回null] – user1619355