Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Shared collection locking in Java

I have a class which contains two Hashmaps with some data. I would like to update/reload data in the maps on a nightly basis (using Quartz job) and want to lock all other threads from reading during data refresh process.

 public class A {

    private Map<String, Object> someMap1 = new ConcurrentHashMap<String, Object>();
    private Map<String, Object> someMap2 = new ConcurrentHashMap<String, Object>();

    public void reloadData() {
        someMap1.clear();
        someMap2.clear();

        // read new data here and re-fill the maps
        ...
    }

    public Object getDataFromMap(String key) {
        // do some logic here and return data from map
        return someObj;
    }
 }

The getDataFromMap() method should be accessible for all 'reader' threads without any blocking in case of data refresh not in progress.

On the other hand, the reloadData() method should wait for all 'readers' to complete and then block the maps from reading and reload the data.

'synchronized' modifier for reloadData() is not a solutions as it blocks all class and all 'readers' if they are in progress in getDataFromMap() logic.

like image 915
ovay Avatar asked Dec 16 '22 18:12

ovay


2 Answers

Your requirement perfectly suits for ReentrantReadWriteLock

    private Map<String, Object> someMap1 = new ConcurrentHashMap<String, Object>();
    private Map<String, Object> someMap2 = new ConcurrentHashMap<String, Object>();
    private final ReentrantReadWriteLock rwl = new ReentrantReadWriteLock();
    private final Lock r = rwl.readLock();
    private final Lock w = rwl.writeLock();

    public Object getDataFromMap(String key) {
        r.lock();
        try {
            // do some logic here and return data from map
            return someObj;
        } finally {
            r.unlock();
        }
    }

    public void reloadData() {
        w.lock();
        try {
            someMap1.clear();
            someMap2.clear();
            // read new data here and re-fill the maps
        } finally {
            w.unlock();
        }
    }
like image 192
Amit Deshpande Avatar answered Jan 11 '23 05:01

Amit Deshpande


Use the Lock class in concurrent package in java. It has ReenterantReadWriteLock.

like image 35
Masood_mj Avatar answered Jan 11 '23 04:01

Masood_mj