Reputation: 23
I have a HashMap which is shared among multiple threads. And any thread can update it. So I synchronise on HashMap object while updating it.
Should I synchronise while reading too ? OR just making it volatile is enough ?
Note: I know I could simply use ConcurentHashMap but want to know whether multi threading affects reading of shared resources which are mutable . If yes, how it affects ?
Also what if it is a simple object (not a collection) or a primitive type.
Upvotes: 0
Views: 419
Reputation: 393
You should also synchronize the read side because any guarantees (visibility in your case) applies only when threads uses same lock, so when you skip synchronizing while reading - it means that reading thread doesn't use the same lock (it doesn't use any lock) which will lead to see stale values by reading thread. See here: Should getters and setters be synchronized?
Upvotes: 0
Reputation: 1
The Java HashMap
documentation states (bolding in the original):
Note that this implementation is not synchronized. If multiple threads access a hash map concurrently, and at least one of the threads modifies the map structurally, it must be synchronized externally. (A structural modification is any operation that adds or deletes one or more mappings; merely changing the value associated with a key that an instance already contains is not a structural modification.) This is typically accomplished by synchronizing on some object that naturally encapsulates the map. If no such object exists, the map should be "wrapped" using the Collections.synchronizedMap method. This is best done at creation time, to prevent accidental unsynchronized access to the map:
Map m = Collections.synchronizedMap(new HashMap(...));
The iterators returned by all of this class's "collection view methods" are fail-fast: if the map is structurally modified at any time after the iterator is created, in any way except through the iterator's own remove method, the iterator will throw a
ConcurrentModificationException
. Thus, in the face of concurrent modification, the iterator fails quickly and cleanly, rather than risking arbitrary, non-deterministic behavior at an undetermined time in the future.Note that the fail-fast behavior of an iterator cannot be guaranteed as it is, generally speaking, impossible to make any hard guarantees in the presence of unsynchronized concurrent modification. Fail-fast iterators throw
ConcurrentModificationException
on a best-effort basis. Therefore, it would be wrong to write a program that depended on this exception for its correctness: the fail-fast behavior of iterators should be used only to detect bugs.
You can not safely change a HashMap
while reading from it. Can you safely climb a ladder while rungs are being removed?
Upvotes: 1
Reputation: 111239
You need to synchronise while reading too, or switch to using a ConcurrentHashMap.
If one thread calls the get
method while another thread is updating the map, it is impossible to predict what will happen. The get
method may throw an exception, because it assumes that the internal structure of the map does not change while it's running.
Upvotes: 1