If in my class I have a field of type ImmutableMap
like:
private ImmutableMap<String, State> states = ImmutableMap.of();
And there is 1 reader thread and 1 writer thread
Reader reads by calling methods like get
on states
with no synchronized
or any kinds of barriers.
Writer thread writes by reassigning states
to new variables like states = ImmutableMap.of(...)
in a synchronized
method (which, as far as I know, provides no guarantee of visibility in the other threads if they have no read memory barriers).
So the whole thing looks like this:
State read(String key) {
return states.get(key);
}
synchronized void write(String key, State value) {
var hashMap = new HashMap<String, State>();
states.forEach(hashMap::put);
hashMap.put(key, value);
states = ImmutableMap.of(hashMap);
}
Is it true, that reader, when reading from a field states
gets a valid value of states
, that existed at one point of the time (linearizability is present)? Can reader thread read some nonsense when reading value of states
due to compiler reordering?
Is it true, that reader, when reading from a field states gets a valid value of states, that existed at one point of the time (linearizability is present)? Can reader thread read some nonsense when reading value of states due to compiler reordering?
In your example each read of states
has no happens-before ordering with writes to states
.
According to the JMM that means every read is allowed to return any of the writes to states
that happen anytime during the program execution.
This includes writes to states
that happen later (in wall-clock time) in the same execution.
This also includes null
- the default initialization value for states
.
Here's the quote from the JLS:
Informally, a read r is allowed to see the result of a write w if there is no happens-before ordering to prevent that read.
To sum up: