This week's book giveaway is in the OO, Patterns, UML and Refactoring forum. We're giving away four copies of Refactoring for Software Design Smells: Managing Technical Debt and have Girish Suryanarayana, Ganesh Samarthyam & Tushar Sharma on-line! See this thread for details.
I'm sure this has been posted before on this list. I have an application where there is a common data structure being shared by multiple threads (say A), which are updating this data structure. Another single thread (B), which is iterating over the entries and taking an action on each entry. (Not updating the data structure). For this application, After going through some documentation, I figured I will have to do the following: 1) Use Collections.synchronizedMap(new HashMap) 2) Synchronize the update operation of the threads A. 3) Little bit confused about the thread B's operation of iterating over the entries. As long as I'm not updating the HashMap with thread B, do I still need to synchronize iterator method of thread B ? If I call the iteration of this HashMap, when one of Thread A is updating the HashMap, I will get unexpected behavior. Is that true ? I read a thread which said "a similar application where an application needs to check and add entries in a data structure". I guess the final solution was "all methods needs to be synchronized and use an un synchronized HashSet". In my case, If I use a Synchronized HashMap, am I gaining anything by using a Synchronized hashmap ? Should I follow the same advice from above ? If I use a Hashtable instead, do I still need to synchronize my add/iterator methods ? -Bindu Can someone help me understand and clear this confusion ?
Do not blindly use a synchronized map. Depending on how the threads A perform their updates, it may buy you nothing and even lure you into writing non-threadsafe code.
The choice is between either using a synchronized map, or synchronizing the method(s) that perform(s) the update operation. A mix makes no sense in most cases.
Whatever option you choose, the iteration must be entirely performed within a synchronized block or method, even if thread B performs no updates. There are a number of reasons for this, the most obvious one is that an iteration will fail if the underlying collection is modified.
Don't use Hashtable. Like all the old-style collections, it forces synchronization on you, has a bloated API, and doesn't sit well inside the Collections framework.
It is probably worth adding a word or two about the choice between a synchronized map and synchronized methods. The key point is: you cannot really synchronize objects, you can only synchronize operations. In a synchronized map, only the primitive operations (methods) on the map are threadsafe. Any more complicated stuff you build upon it is not. See what happens if the updates performed by threads A are just a bit more complicated:The snippet above could come from a caching algorithm. Even if "map" were synchronized, it would not be threadsafe. Why? Well, what happens if another thread adds "myKey" to the map between the first and the fourth line? Or worse, removes it between the first and the second? The obvious solution is to put the entire chunk of code in a synchronized method or block, so that the entire "read-modify" operation is protected against interference from other threads. This illustrates that the operation, rather than the (map) object, needs to be synchronized. Note also that the moment you synchronize the above block of code, you no longer have any benefit from using a synchronized map and are better off with a plain vanilla one. Does this help? - Peter [ March 07, 2002: Message edited by: Peter den Haan ]
Joined: May 23, 2001
IT DOES. it does help me a lot to understand the concepts clearly. Thanks Peter.