1

I have the following JedisCluster impl which I want to make thread safe -

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);
    }

The following are the threads -

  • 1 write thread which will update the state when a node is added/removed from a cluster - This happens very rarely
  • 1 read thread which will frequently read making call to getMaster() and getPool().

I want to know the best strategy to handle the above scenario using concurrency. I would like to avoid synchronize at method level as the read are very frequent.

user1619355
  • 429
  • 1
  • 4
  • 17
  • In general you should synchronize only the _critical section_s of the code, the minimum code section that accesses shared data. You haven't told us which data are shared, but I'm guessing `hostPorts` and `hostPool`, which should be `final`. If that's correct, your entire `getMaster`, `getPool`, and `add` method bodies need to be synchronized on whatever monitor or lock you use, and the two `remove` calls within the `remove` method need to be in a synchronized block together. (`add` and `remove` in your example won't compile.) – Lew Bloch Jun 15 '17 at 22:52

1 Answers1

1

Use a ReadWriteLock, which generally means a ReentrantReadWriteLock:

A ReadWriteLock maintains a pair of associated locks, one for read-only operations and one for writing. The read lock may be held simultaneously by multiple reader threads, so long as there are no writers. The write lock is exclusive.

Andreas
  • 154,647
  • 11
  • 152
  • 247
  • even if i use writeLock inside add/remove and readLock inside getMaster/getPool, there can be the following situation where i cannot avoid corruption - 1] reader gets master 2] writer removes the node (same which reader had fetched earlier) 3] reader calls getPool passing the master fetched in step 1] which would return null as it was removed in step 2] – user1619355 Jun 16 '17 at 01:57