To perform lock-free and wait-free lazy initialization I do the following:
private AtomicReference<Foo> 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;
}
}
and it works pretty well except for one thing: if two threads see instance null, they both create a new object, and only one is lucky to set it by CAS operation, which leads to waste of resources.
Does anyone suggest another lock-free lazy initialization pattern, which decrease probability of creating two expensive objects by two concurrent threads?
If you want true lock-freedom you will have to do some spinning. You can have one thread 'win' creation rights but the others must spin until it's ready.
This obviously has its problems of busy spinning (you can put a sleep or yield in there), but I would probably still recommend Initialization on demand.