Are size (), put (), remove (), get () atomic in Java synchronized HashMap?

I declare a Java map as

Map<String, String> map = Collections.synchronizedMap(new HashMap<String, String>()); 

to solve the problems of concurrency and synchronization on the map for all operations on it. However, I read that synchronization is not required with synchronizedMap , when operations are atomic. I checked the Java API and the HashMap documentation does not seem to mention which ones are atomic, so I'm not sure if there are any.

I will synchronize the following calls on the map:

 map.size() map.put() map.remove() map.get() 

But if some of them are atomic, it seems that they do not need synchronization. What are the atoms?

+6
source share
3 answers

The synchronized card, as the name implies, is synchronized. Each operation on it is atomic with respect to any other operation on it.

You can think of it as if every method of your synchronized map is declared with the synchronized .

Please keep in mind that although individual operations are atomic, if you combine them, they are no longer atoms, for example:

 String value = map.get("key"); map.put("key", value+"2"); 

not equivalent to your custom synced code:

 synchronized (map) { String value = map.get("key"); map.put("key", value+"2"); } 

but rather:

 synchronized (map) { String value = map.get("key"); } synchronized (map) { map.put("key", value+"2"); } 
+10
source

A HashMap not guaranteed to have atomic operations. Calling any of its methods from different threads (even size() ) can damage the map. However, a map obtained using Collections.synchronizedMap will have every call synchronized (and therefore thread safe).

However, you may need a higher level of synchronization. For example, if you check if a key is present, read the size, or otherwise access something from the card, and then do something else with the card based on the result, the card may have changed between two calls. In this case, you need a synchronized block to make the whole transaction atomic rather than a synchronized card (which just makes every call an atom).

+5
source

The card itself is synchronized, not some internal locks. To perform several operations on the card, a synchronized block is required. In any case, if you are using JDK 1.6 or higher, you should consider using ConcurrentHashMap.

ConcurrentHashMap is optimal when you need to ensure data consistency, and each of your flows needs the current map view. If performance is critical and each stream only inserts data onto the card, and reading is less frequent, then use the path you describe. However, performance can only be worse when only one thread accesses the ConcurrentHashMap at a time, but significantly better when multiple threads access the map at a time.

+3
source

Source: https://habr.com/ru/post/971676/


All Articles