Should I use a thread-safe implementation of the card when I read it?

If I do the following.

  • Create a HashMap (in the final field)
  • HashMap Fill
  • Wrap HashMap with non-modifiable shell Map
  • Launch other themes that will have access but will not change the map.

As far as I understand, the map was “safely published” because other threads were started after the Map was completely full, so I think it’s normal to access the Map from several threads, because after this point it cannot be changed.

Is it correct?

+7
source share
5 answers

This applies very well to the map itself. But you need to understand that creating a map is not modifiable, it will only make the card unmodifiable and not its keys and values. Therefore, if you have, for example, Map<String, SomeMutableObject> , for example Map<String, List<String>> , then the streams will still be able to change the value, for example, map.get("foo").add("bar"); . To avoid this, you should also make the keys / values ​​immutable / immutable.

+11
source

As I understand it, the map was “safely published” because other threads were started after the Map was completely full, so I think it’s normal to access the Map from several streams, since it cannot be changed after of this paragraph.

Yes. Just make sure other threads are running synchronously, i.e. Make sure you have an up-to-date relationship between publishing a map and starting streams.

This is discussed in this blog post :

[...] This is how Collections.unmodifiableMap () works.

[...]

Due to the special meaning of the final keyword, instances of this class can be shared across multiple threads without any additional synchronization ; when another thread calls get () on the instance, it is guaranteed to get the object that you put into the map without additional synchronization. You should probably use something thread safe to perform handoff between threads (like LinkedBlockingQueue or something else), but if you forget to do this, you still have a guarantee.

+1
source

You're right. There is no need to provide exclusive access to the data structure by various streams using mutex'es or otherwise, since it is immutable. This usually greatly improves performance.

Also note that if you only wrap the original map, and not create a copy, that is, the unmodifiable method of delegating the map causes a further internal HashMap, changing the base map can lead to problems in the race conditions.

0
source

Immutable card is born for thread safety. You can use ImmutableMap from Guava.

0
source

In short, you do not need the card to be thread safe unless the readings are destructive and the map link is safely published to the client.

In this example, there are two important things going on before the relationship established here. Publication of the final field (if and only if the population runs inside the constructor, and the link does not flow outside the constructor) and calls to start the threads.

Everything that changes the card after these calls when the client reads from the card is not published securely.

We have, for example, CopyOnWriteMap , which contains a non-stream card underlying, which is copied every time. This happens as quickly as possible in situations where there are many other reads than writes (an example of configuration caching is a good example).

However, if the intention is really not to change the map, setting an unchanged version of the map in the field is always the best way, as this ensures that the client sees the right thing.

Finally, there are some Map implementations that have destructive readings, such as LinkedHashMap with access order, or WeakHashMap , where entries may disappear. These types of cards should be accessed sequentially.

0
source

All Articles