Lazy initialization without synchronization or volatile keyword
concurrency, java, multithreading
Solution
This statement sounds a little bit cryptic. However, I guess HLS refers to the case when you lazily initialize an instance field and don't care if several threads performs this initialization more than once. As an example, I can point to the `hashCode()` method of `String` class:
private int hashCode;
public int hashCode() {
int hash = hashCode;
if (hash == 0) {
if (count == 0) {
return 0;
}
final int end = count + offset;
final char[] chars = value;
for (int i = offset; i < end; ++i) {
hash = 31*hash + chars[i];
}
hashCode = hash;
}
return hash;
}
As you can see access to the `hashCode` field (which holds cached value of the computed String hash) is not synchronized and the field isn't declared as `volatile`. Any thread which calls `hashCode()` method will still receive the same value, though `hashCode` field may be written more than once by different threads.
This technique has limited usability. IMHO it's usable mostly for the cases like in the example: a cached primitive/immutable object which is computed from the others final/immutable fields, but its computation in the constructor is an overkill.
Problem
The other day Howard Lewis Ship posted a blog entry called "Things I Learned at Hacker Bed and Breakfast", one of the bullet points is: A Java instance field that is assigned exactly once via lazy initialization does not have to be synchronized or volatile (as long as you can accept race conditions across threads to assign to the field); this is from Rich Hickey On the face of it this seems at odds with the accepted wisdom about visibility of changes to memory across threads, and if this is covered in the Java Concurrency in Practice book or in the Java language spec then I have missed it. But this was something HLS got from Rich Hickey at an event where Brian Goetz was present, so it would seem there must be something to it. Could someone please explain the logic behind this statement?