Manthri Anvesh
Manthri Anvesh

Reputation: 95

Applying lock on HashMap

I have a HashMap which is static and three threads which try to access HashMap simultaneously from their corresponding class`s.

each thread task is get list value of a specified key, process some operations on the list(modify the list). and put the processed list in HashMap.

I want to make other threads trying to access the HashMap wait until current thread finishes the processing and modifying the HashMap.

in some situation, the flow is like this,

thread A is retrieved HashMap, while Thread A is processing on the list of HashMap, other Thread B retrieves the HashMap and starts its processing.

Actual behaviour has to be like: Thread A -> retrieves HashMap -> process -> put value in HashMap. Thread B -> retrieves HashMap -> process -> put value in HashMap. Thread C -> retrieves HashMap -> process -> put value in HashMap.

logic :

  1. apply lock on HashMap
  2. retrieve.
  3. process.
  4. put into HashMap.
  5. release lock.

help me in converting the logic to code, or any suggestions are accepted with smile.

Upvotes: 1

Views: 8956

Answers (3)

Tiny Rick
Tiny Rick

Reputation: 276

You can really make use the ReentrantReadWriteLock. Here is the link for that.

Javadoc for ReadWriteReentrant lock

I would implement the feature as something like this..........

public class Test {

        private Map<Object, Object> map = new HashMap<>();
        private ReentrantReadWriteLock reentrantReadWriteLock = new ReentrantReadWriteLock();

        public void process() {
            methodThatModifiesMap();
            methodThatJustReadsmap();
        }

        private void methodThatModifiesMap() {
            //if the code involves modifying the structure of the map like 'put(), remove()' i will acquire the write reentrantReadWriteLock
            reentrantReadWriteLock.writeLock().lock();
            try {
                //DO your thing and put() or remove from map
            }
            finally {
                //Dont forget to unlock
                reentrantReadWriteLock.writeLock().unlock();
            }
        }

        private void methodThatJustReadsmap() {
            // if all you are doing is reading ie 'get()'
            reentrantReadWriteLock.readLock().lock(); // this does not block other reads from other threads as long as there is no writes during this thread's read
            try {

            } finally {
                reentrantReadWriteLock.readLock().unlock();
            }
        }

    }

Not only your map is thread-safe, the throughput is better too.

Upvotes: 4

leo017
leo017

Reputation: 55

You can either use ConcurrentHashMap as suggested above or use class level locks.What I mean by it is by using synchronized keyword on static method.eg

public class SynchronizedExample extends Thread {
    static HashMap map = new HashMap();
    public synchronized static void execute() {
        //Modify and read HashMap
    }

    public void run() {
            execute();
    }
}

Also as others mentioned it will incur performance bottlenecks if you use synchronized methods, depends on how atomic functions you make. Also you can check class level locks vs object level locks(Although its almost same, but do check that.)

Upvotes: 0

vlaxmi
vlaxmi

Reputation: 468

You can use ConcurrentHashMap instead of HashMap. The ConcurrentHashMap gives better performance and reduces overhead of locking the whole HashMap while other thread is accessing it. You can find more details on this page as well - http://crunchify.com/hashmap-vs-concurrenthashmap-vs-synchronizedmap-how-a-hashmap-can-be-synchronized-in-java/

Upvotes: 1

Related Questions