Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Collections.synchronizedMap

Tags:

java

From javadocs

Map m = Collections.synchronizedMap(new HashMap());
      ...
  Set s = m.keySet();  // Needn't be in synchronized block
      ...
  synchronized(m) {  // Synchronizing on m, not s!
      Iterator i = s.iterator(); // Must be in synchronized block
      while (i.hasNext())
          foo(i.next());
  }

Two queries:

1) Is Set returned by m.keySet() also a collection wrapper or just an unsynchronized set?

EDIT:

2)Is it necessary to synchronize on m in

 synchronized(m) {  // Synchronizing on m, not s!

Can't we synchronize on s instead of m?

like image 404
a Learner Avatar asked Jan 16 '23 15:01

a Learner


2 Answers

1: Yes it returns a synchronized set that shares a mutex with the Map.

2: Yes you need to hold the lock manually while iterating. If you don't changes can be made in between calls to next() and you'll still have problems. Remember it is part of the specification of HashMap that if another thread, for example does an m.put("foo", "bar"); in between two of your calls to i.next(), then next() will throw ConcurrentModificationException. To prevent this, you lock the whole map so nobody can change it until you're done with the iterator. Locking just the set wouldn't stop anybody from adding to the map.

If you need to iterate while concurrent access may be happening, you should look at implementations of ConcurrentMap to make your life a lot easier.

like image 183
Affe Avatar answered Jan 25 '23 15:01

Affe


1) The set returned is a SynchronizedSet that uses the same mutex to lock on.

2) The map does not synchronise on itself, rather a separate mutex object, so synchronizing on the map will not stop other threads in that have access to the map from modifying it. This would only work if all of the code that modified the map, also synchronized on the map. The map does synchronise on itself, but oddly refers to itself using a seperate mutex variable. Therefore synchronising on the map will prevent other modifications to the map via the syncronised wrapper. Note that the same mutex is used in the synronised set returned by the keySet() method.

like image 25
SimonC Avatar answered Jan 25 '23 14:01

SimonC