Reputation: 4694
I have a java thread safe map which stores String to Object mappings:
ConcurrentHashMap<String, MyObject> map = new ConcurrentHashMap<>();
Here MyObject is a user defined class. Now consider the following method:
public void replace(String key, MyObject o) {
MyObject m = map.get("somekey");
synchronized(m) {
// Modify some internal components of m
// and some other objects related to m
}
}
My intention here is I want to maximise performance by not putting a lock on the whole class but only on threads that try to access the same key in the map. Basically every time an entry is replaced in the map (not added) this part of the code gets executed. Something like:
public void put(String key, MyObject o) {
if (map.putIfAbsent(key, o) == null){ //do something
}
else {
replace(key, o);
}
}
For all practical purposes we can assume that this is the only method through which a reference to MyObject can be changed. Is this implementation thread safe?
Upvotes: 1
Views: 176
Reputation: 44965
Is the following implementation thread safe?
It depends on how you access and modify your instances of MyObject
in your code, if you always access and modify a given instance of MyObject
within a synchronized block using this MyObject
instance as object's monitor then yes it would be thread safe, otherwise it won't be.
Your put
method is not thread safe as putIfAbsent
and replace
are not executed atomically which could lead to race condition issues, use merge(K key, V value, BiFunction<? super V,? super V,? extends V> remappingFunction)
to do the exact same thing but atomically as next:
public void put(String key, MyObject o) {
map.merge(
key, o,
(v1, v2) -> {
// Modify some internal components of v1
// and some other objects related to v1
return v2;
}
);
}
Upvotes: 3