A specialized implementation of the {@code ConcurrentInitializer} interfacebased on an {@link AtomicReference} variable.
This class maintains a member field of type {@code AtomicReference}. It implements the following algorithm to create and initialize an object in its {@link #get()} method:
- First it is checked whether the {@code AtomicReference} variable containsalready a value. If this is the case, the value is directly returned.
- Otherwise the {@link #initialize()} method is called. This method must bedefined in concrete subclasses to actually create the managed object.
- After the object was created by {@link #initialize()} it is checkedwhether the {@code AtomicReference} variable is still undefined. This has tobe done because in the meantime another thread may have initialized the object. If the reference is still empty, the newly created object is stored in it and returned by this method.
- Otherwise the value stored in the {@code AtomicReference} is returned.
Because atomic variables are used this class does not need any synchronization. So there is no danger of deadlock, and access to the managed object is efficient. However, if multiple threads access the {@code AtomicInitializer} object before it has been initialized almost at the sametime, it can happen that {@link #initialize()} is called multiple times. Thealgorithm outlined above guarantees that {@link #get()} always returns thesame object though.
Compared with the {@link LazyInitializer} class, this class can be moreefficient because it does not need synchronization. The drawback is that the {@link #initialize()} method can be called multiple times which may beproblematic if the creation of the managed object is expensive. As a rule of thumb this initializer implementation is preferable if there are not too many threads involved and the probability that multiple threads access an uninitialized object is small. If there is high parallelism, {@link LazyInitializer} is more appropriate.
@author Apache Software Foundation
@version $Id: AtomicInitializer.java 929189 2010-03-30 16:49:22Z oheger $
@param < T> the type of the object managed by this initializer class