2017-06-15 38 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