What happens when we pass the hash table inside Collections.synchronizedMap ()

Today I asked a question in my interview. The question is that Collections.synchronizedMap () is used to synchronize cards that by default are not thread safe, like hashmap. His question is that we can transfer any card inside this method. So, what is the effect when we pass the hash table inside this method, because the hash table is synchronized by default.

+6
source share
5 answers

If you see the code in the SynchronizedCollection . Methods delegate the call to the base collection, but adding a synchronized block on top of the call is something like this

 public int size() { synchronized (mutex) {return c.size();} } 

The size implementation looks like this: HashTable class

 public synchronized int size() { return count; } 

So, if you go to HashTable before the SynchronizedCollection , the thread accessing the SynchronizedCollection will have to take locks at 2 levels once for the synchronized block, and the other for the synchronized method. If there are other threads directly linked to the HashTable, they can block threads using the SynchronizedCollection , even if the thread got a lock on the SynchronizedCollection .

0
source

The behavior of the card will be the same, but the performance will depend on the fact that each method will receive two synchronization locks instead of one.

For example, consider calling the size() method on the resulting map. The implementation in the Collections.SynchronizedMap class is as follows:

 public int size() { synchronized(mutex) {return m.size();} // first lock } 

... where m.size() calls the implementation in the Hashtable :

 public synchronized int size() { // second lock return count; } 

The first lock object is the mutex field in the SynchronizedMap . The second lock is implicit - the Hashtable instance itself.

+3
source

You will have two levels of synchronization: one at the level of the most synchronized card implemented by the mutex object, and one at the level of the wrapped instance:

 public boolean isEmpty() { // first level synchronization synchronized(mutex) { // second level synchronization if c is a Hashtable return c.isEmpty(); } } 

Additional synchronization is not needed and may lead to performance degradation.

Another effect is that you won’t be able to use the APIs from the Hashtable , such as Hashtable#elements , since the Map collection is now wrapped.

+2
source

It will be wrapped in a SynchronizedMap , from java.util.Collections :

 public static <K,V> Map<K,V> synchronizedMap(Map<K,V> m) { return new SynchronizedMap<>(m); } 

The synchronizedMap() method does not distinguish between Map types passed to it.

+1
source

"His question is that we can transfer any card inside this method."

The answer is yes, because the SynchronizedMap constructor accepts every Map in its signature.

"So, what is the effect when we pass the hash table inside this method, because the hash table is synchronized by default"

Answer: We show ignorance of ConcurrentHashMap , which is most likely used for use instead of a blocking implementation.

0
source

Source: https://habr.com/ru/post/977877/


All Articles