Can get, put & remove elemetn in HashMap without iteration cause ConcurrentModificationException?
Can get, put & remove elemetn in HashMap without iteration cause ConcurrentModificationException?
I have a static hashMap, shared with multiple threads. I am not iterating the map at all but just uses the get
, put
, remove
. Is it safe from ConcurrentModificationException
?
get
put
remove
ConcurrentModificationException
The method looks like this
private static Map<Long, Integer> TRACKER = new HashMap<Long,Integer>();
public static void track(Long tid, boolean b)
if (b)
if (TRACKER.containsKey(tid))
TRACKER.put(tid, TRACKER.get(tid) + 1);
else
TRACKER.put(tid, 1);
else
Integer n = TRACKER.get(tid);
if (n != null)
n = n -1;
if (n == 0)
TRACKER.remove(tid);
else
TRACKER.put(tid, n);
Nothing will cause a concurrent modification exception...and that's bad, because concurrent modification is happening, and breaking things, but it can't figure it out and throw an exception to warn you.
– Louis Wasserman
Sep 7 '18 at 3:48
2 Answers
2
Is it safe from ConcurrentModificationException
?
ConcurrentModificationException
It is safe from ConcurrentModificationException
. That exception is only thrown by methods that iterate (in some sense) the map or one of its views using a conventional iterator or a spliterator.
ConcurrentModificationException
However, since HashMap
is not a thread-safe class, if you use it from multiple threads without proper external external synchronization, bad things can happen. These include (in order of increasing badness)
HashMap
size()
Your example code is unsafe ... but you won't get a "fast fail" ConcurrentModificationException
. Instead you are likely to get inexplicable errors at "random" times that are difficult to reproduce.
ConcurrentModificationException
If multiple threads are performing get
, put
& remove
operations on a HashMap
, without proper synchronization, some bad things like size() reporting missing / lost entries, unexpected NPEs ... even infinite loops may happen.
get
put
remove
HashMap
HashMap documentation says -
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.) ...
Thanks Stephen.
You probably could update the values concurrently without synchronization after reading those docs, But I can't imaging the mechanisms needed to do the checks required to update the value without accidentally putting a new value. It would have to be incredibly contrived.
– Ryan The Leach
Sep 7 '18 at 1:52
Thanks for contributing an answer to Stack Overflow!
But avoid …
To learn more, see our tips on writing great answers.
Required, but never shown
Required, but never shown
By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.
There's nothing in the code you're showing us here to cause a ConcurrentModificationException.
– khelwood
Sep 6 '18 at 23:41