Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Safe publication example in Java Concurrency in Practice

Java Concurrency in Practice says you can safely publish an effectively immutable object (say, a Date object that you construct and never change again) by sticking it into a synchronized collection like the following (from the book, page 53):

public Map<String, Date> lastLogin =
    Collections.synchronizedMap(new HashMap<String, Date>())

I understand that any Date object put into this map will be visible (at least in its initial but completely constructed state) once placed into this synchronized map, but only once other threads can obtain the reference to this Map object.

Since the reference field lastLogin has none of the properties of fields that guarantee visibility (final, volatile, guarded, or initialized by a static initializer), I think that it's possible the map itself will not show up in a completely constructed state to other threads, therefore putting the cart before the horse. Or am I missing something?

like image 490
nabbed Avatar asked May 10 '17 03:05

nabbed


People also ask

Is Java Concurrency in Practice still valid?

TL: DR — Yes, Java Concurrency in Practice is still valid and one of the best books to learn Java multithreading and concurrency concepts.

What is concurrency in Java with example?

Concurrency is the ability to run several or multi programs or applications in parallel. The backbone of Java concurrency is threads (a lightweight process, which has its own files and stacks and can access the shared data from other threads in the same process).

How do you resolve concurrency issues in Java?

The simplest way to avoid problems with concurrency is to share only immutable data between threads. Immutable data is data which cannot be changed. To make a class immutable define the class and all its fields as final. Also ensure that no reference to fields escape during construction.

What is safe publication?

Safe publication makes all the values written before the publication visible to all readers that observed the published object. It is a great simplification over the JMM rules of engagement with regards to actions, orders and such.


1 Answers

Your suspicion is half right, in that the value of lastLogin is not guaranteed to be visible to other threads. Because lastLogin is not volatile or final, another thread may read it as null.

However, you do not need to worry that other threads will see an incomplete version of the map. Collections.synchronizedMap(...) returns an instance of a private class with final fields. JLS section 17.5 says:

The usage model for final fields is a simple one: Set the final fields for an object in that object's constructor; and do not write a reference to the object being constructed in a place where another thread can see it before the object's constructor is finished. If this is followed, then when the object is seen by another thread, that thread will always see the correctly constructed version of that object's final fields.

SynchronizedMap follows these rules, so another thread reading lastLogin will either read null or a reference to the fully constructed map, never a reference to an incomplete or unsafe version of the map.

like image 133
Kevin Krumwiede Avatar answered Oct 30 '22 18:10

Kevin Krumwiede