Today I have asked a question in my interview. The question is that Collections.synchronizedMap() is used to synchronize the map which are by default not thread safe like hashmap. His question is but we can pass any kind of map inside this method. So what is the effect when we pass a hashtable inside this method because hashtable is by default synchronized.
The behavior of the map will be the same, but the performance will be affected, because each method will acquire two synchronization locks instead of one.
For example, consider calling the method size()
on the resulting map. The implementation in the Collections.SynchronizedMap
class looks like this:
public int size() {
synchronized(mutex) {return m.size();} // first lock
}
... where, m.size()
calls the implementation in Hashtable
:
public synchronized int size() { // second lock
return count;
}
The first lock object is the mutex
field in SynchronizedMap
. The second lock is implicit - the Hashtable
instance itself.
You would have two synchronization levels: one at the level of the synchronized map itself, implemented by a 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();
}
}
The additional synchronization is not needed and can lead to lower performance.
Another effect is that you won't be able to use API from Hashtable
like Hashtable#elements
since the wrapped collection is now strictly a Map
instance.
It will get wrapped into 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 the types of Map
s passed into it.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With