Guava Suppliers-class contains MemoizingSupplier:
static class MemoizingSupplier<T> implements Supplier<T>, Serializable {
final Supplier<T> delegate;
transient volatile boolean initialized;
// "value" does not need to be volatile; visibility piggy-backs
// on volatile read of "initialized".
transient T value;
MemoizingSupplier(Supplier<T> delegate) {
this.delegate = delegate;
}
@Override public T get() {
// A 2-field variant of Double Checked Locking.
if (!initialized) {
synchronized (this) {
if (!initialized) {
T t = delegate.get();
value = t;
initialized = true;
return t;
}
}
}
return value;
}
@Override public String toString() {
return "Suppliers.memoize(" + delegate + ")";
}
private static final long serialVersionUID = 0;
}
Could someone explain what does that comment mean?
"value" does not need to be volatile; visibility piggy-backs on volatile read of "initialized".
How can volatile on "initialized" field affect "value" field? According to this article we can get inconsistent combination of "initialized" and "value" fields (eg. true+null). Am I wrong?