What are some recommended approaches to achieving thread-safe lazy initialization? For instance,
// Not thread-safe
public Foo getI
This can be done in lock-free manner by using AtomicReference as instance holder:
// in class declaration
private AtomicReference instance = new AtomicReference<>(null);
public Foo getInstance() {
Foo foo = instance.get();
if (foo == null) {
foo = new Foo(); // create and initialize actual instance
if (instance.compareAndSet(null, foo)) // CAS succeeded
return foo;
else // CAS failed: other thread set an object
return instance.get();
} else {
return foo;
}
}
Main disadvantage here is that multiple threads can concurrently instantiate two or more Foo objects, and only one will be lucky to be set up, so if instantiation requires I/O or another shared resource, this method may not be suitable.
At the other side, this approach is lock-free and wait-free: if one thread which first entered this method is stuck, it won't affect execution of others.