Securely publish java.util.concurrent collections

Is there no redundancy in this code?

public class Test { private volatile Map<String, String> map = null; public void resetMap() { map = new ConcurrentHashMap<>(); } public Map<String, String> getMap() { return map; } } 

In other words, does map = new ConcurrentHashMap<>(); provide map = new ConcurrentHashMap<>(); any guarantee of visibility?

As far as I can see, the only guarantee of ConcurrentMap is:

Actions in a stream before placing an object in ConcurrentMap as a key or value - before actions after accessing or deleting this object from ConcurrentMap in another stream.

What about other thread safe collections in java.util.concurrent (CopyOnWriteArrayList, etc.)?

+6
source share
6 answers

volatile not redundant when changing map links. that is, ConcurrentMap provides parties with only the contents of the contents of the collection, and not links to it.

An alternative would be

 public class Test { private final Map<String, String> map = new ConcurrentHashMap<>(); public void resetMap() { map.clear(); } public Map<String, String> getMap() { return map; } } 

What about other thread safe collections in java.util.concurrent (CopyOnWriteArrayList, etc.)?

Only collection behavior is thread safe. The reference to the collection is not thread safe, elements in the collection do not become thread safe, adding them to the collection.

+8
source

volatile needed here. This refers to the link, not to what it refers to. In other words, it does not matter that the object is thread safe, other threads will not see the new value of the map field (for example, they can see a previously mapped parallel map or null ).

Also, even if your object was immutable (e.g. String ), you still need volatile , not to mention other non- CopyOnWriteArrayList like CopyOnWriteArrayList .

+6
source

These are not just links. As a rule, without the volatile other threads can observe a new reference to the object, but observe the object in a partially constructed state. In general, it is not easy to find out, even after consulting the documentation, which objects are safe for publication on a data race. It is interesting to note that JLS guarantees this for thread-safe immutable objects , therefore, if these two properties are indicated in the documents, this should be sufficient.

ConcurrentHashMap is obviously not an immutable object, so it is not used, and the documents do not say anything about publishing as a result of data race. By carefully checking the source code, we can conclude that it is really safe, but I would not recommend relying on such conclusions if this property were not clearly documented.

+4
source

Memory Consistency Properties

It is recorded in an unstable field - before each subsequent reading of the same field. Records and readings of variable fields have similar memory matching effects as input and output monitors, but do not entail a mutual exclusion lock.

Actions in a stream before placing an object in any parallel collection will occur - before actions after accessing or removing this element from the collection in another stream.

0
source

OK - I managed to build an example that breaks (on my machine: JDK 1.7.06 / Win 7 64 bit), if the field is not changeable - the program never prints Loop exited , if the card is unstable - it makes Loop exited , if the card is unstable . Q.E.D.

 public class VolatileVisibility extends Thread { Map<String, String> stop = null; public static void main(String[] args) throws InterruptedException { VolatileVisibility t = new VolatileVisibility(); t.start(); Thread.sleep(100); t.stop = new ConcurrentHashMap<>(); //write of reference System.out.println("In main: " + t.stop); // read of reference System.out.println("Waiting for run to finish"); Thread.sleep(200); System.out.println("Still waiting"); t.stop.put("a", "b"); //write to the map Thread.sleep(200); System.exit(0); } public void run() { System.out.println("In run: " + stop); // read of reference while (stop == null) { } System.out.println("Loop exited"); } } 
0
source

My impression is that Doug Lea parallel objects can be safely published on a data schedule, so that they are "thread safe" even if they are not used correctly. Although he probably would not have published it publicly.

0
source

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


All Articles