Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java synchronized block vs. Collections.synchronizedMap

Is the following code set up to correctly synchronize the calls on synchronizedMap?

public class MyClass {   private static Map<String, List<String>> synchronizedMap = Collections.synchronizedMap(new HashMap<String, List<String>>());    public void doWork(String key) {     List<String> values = null;     while ((values = synchronizedMap.remove(key)) != null) {       //do something with values     }   }    public static void addToMap(String key, String value) {     synchronized (synchronizedMap) {       if (synchronizedMap.containsKey(key)) {         synchronizedMap.get(key).add(value);       }       else {         List<String> valuesList = new ArrayList<String>();         valuesList.add(value);         synchronizedMap.put(key, valuesList);       }     }   } } 

From my understanding, I need the synchronized block in addToMap() to prevent another thread from calling remove() or containsKey() before I get through the call to put() but I do not need a synchronized block in doWork() because another thread cannot enter the synchronized block in addToMap() before remove() returns because I created the Map originally with Collections.synchronizedMap(). Is that correct? Is there a better way to do this?

like image 230
Ryan Ahearn Avatar asked Feb 19 '09 20:02

Ryan Ahearn


1 Answers

Collections.synchronizedMap() guarantees that each atomic operation you want to run on the map will be synchronized.

Running two (or more) operations on the map however, must be synchronized in a block. So yes - you are synchronizing correctly.

like image 134
Yuval Adam Avatar answered Oct 05 '22 12:10

Yuval Adam