Lock-free and wait-free thread-safe lazy initialization
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.
private AtomicBoolean canWrite = new AtomicBoolean(false); private volatile Foo foo; public Foo getInstance() { while (foo == null) { if(canWrite.compareAndSet(false, true)){ foo = new Foo(); } } return foo;}
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.
I think you need to have some synchronization for the object creation itself. I would do:
// The atomic reference itself must be final!private final AtomicReference<Foo> instance = new AtomicReference<>(null);public Foo getInstance() { Foo foo = instance.get(); if (foo == null) { synchronized(instance) { // You need to double check here // in case another thread initialized foo Foo foo = instance.get(); if (foo == null) { foo = new Foo(); // actual initialization instance.set(foo); } } } return foo;}
This is a very common pattern especially for lazy singletons. Double checked locking minimizes the number of times the synchronized
block is actually executed.
I would probably go with the lazy init Singleton pattern:
private Foo() {/* Do your heavy stuff */}private static class CONTAINER { private static final Foo INSTANCE = new Foo();}public static Foo getInstance() { return CONTAINER.INSTANCE;}
I do not actually see any reason on using an AtomicReference member field for itself.