Class LazyInitializer<T>
- java.lang.Object
-
- org.apache.commons.lang3.concurrent.AbstractConcurrentInitializer<T,ConcurrentException>
-
- org.apache.commons.lang3.concurrent.LazyInitializer<T>
-
- Type Parameters:
T
- the type of the object managed by the initializer.
- All Implemented Interfaces:
ConcurrentInitializer<T>
,FailableSupplier<T,ConcurrentException>
public class LazyInitializer<T> extends AbstractConcurrentInitializer<T,ConcurrentException>
This class provides a generic implementation of the lazy initialization pattern.Sometimes an application has to deal with an object only under certain circumstances, e.g. when the user selects a specific menu item or if a special event is received. If the creation of the object is costly or the consumption of memory or other system resources is significant, it may make sense to defer the creation of this object until it is really needed. This is a use case for the lazy initialization pattern.
This abstract base class provides an implementation of the double-check idiom for an instance field as discussed in Joshua Bloch's "Effective Java", 2nd edition, item 71. The class already implements all necessary synchronization. A concrete subclass has to implement the
initialize()
method, which actually creates the wrapped data object.As an usage example consider that we have a class
ComplexObject
whose instantiation is a complex operation. In order to apply lazy initialization to this class, a subclass ofLazyInitializer
has to be created:public class ComplexObjectInitializer extends LazyInitializer<ComplexObject> { @Override protected ComplexObject initialize() { return new ComplexObject(); } }
Access to the data object is provided through the
get()
method. So, code that wants to obtain theComplexObject
instance would simply look like this:// Create an instance of the lazy initializer ComplexObjectInitializer initializer = new ComplexObjectInitializer(); ... // When the object is actually needed: ComplexObject cobj = initializer.get();
If multiple threads call the
get()
method when the object has not yet been created, they are blocked until initialization completes. The algorithm guarantees that only a single instance of the wrapped object class is created, which is passed to all callers. Once initialized, calls to theget()
method are pretty fast because no synchronization is needed (only an access to a volatile member field).- Since:
- 3.0
-
-
Nested Class Summary
Nested Classes Modifier and Type Class Description static class
LazyInitializer.Builder<I extends LazyInitializer<T>,T>
Builds a new instance.-
Nested classes/interfaces inherited from class org.apache.commons.lang3.concurrent.AbstractConcurrentInitializer
AbstractConcurrentInitializer.AbstractBuilder<I extends AbstractConcurrentInitializer<T,E>,T,B extends AbstractConcurrentInitializer.AbstractBuilder<I,T,B,E>,E extends java.lang.Exception>
-
-
Field Summary
Fields Modifier and Type Field Description private static java.lang.Object
NO_INIT
A unique value indicating an un-initialzed instance.private T
object
Stores the managed object.-
Fields inherited from interface org.apache.commons.lang3.function.FailableSupplier
NUL
-
-
Constructor Summary
Constructors Modifier Constructor Description LazyInitializer()
Constructs a new instance.private
LazyInitializer(FailableSupplier<T,ConcurrentException> initializer, FailableConsumer<T,ConcurrentException> closer)
Constructs a new instance.
-
Method Summary
All Methods Static Methods Instance Methods Concrete Methods Modifier and Type Method Description static <T> LazyInitializer.Builder<LazyInitializer<T>,T>
builder()
Creates a new builder.T
get()
Returns the object wrapped by this instance.protected ConcurrentException
getTypedException(java.lang.Exception e)
Gets an Exception with a type of E as defined by a concrete subclass of this class.boolean
isInitialized()
Tests whether this instance is initialized.-
Methods inherited from class org.apache.commons.lang3.concurrent.AbstractConcurrentInitializer
close, initialize
-
-
-
-
Field Detail
-
NO_INIT
private static final java.lang.Object NO_INIT
A unique value indicating an un-initialzed instance.
-
object
private volatile T object
Stores the managed object.
-
-
Constructor Detail
-
LazyInitializer
public LazyInitializer()
Constructs a new instance.
-
LazyInitializer
private LazyInitializer(FailableSupplier<T,ConcurrentException> initializer, FailableConsumer<T,ConcurrentException> closer)
Constructs a new instance.- Parameters:
initializer
- the initializer supplier called byAbstractConcurrentInitializer.initialize()
.closer
- the closer consumer called byAbstractConcurrentInitializer.close()
.
-
-
Method Detail
-
builder
public static <T> LazyInitializer.Builder<LazyInitializer<T>,T> builder()
Creates a new builder.- Type Parameters:
T
- the type of object to build.- Returns:
- a new builder.
- Since:
- 3.14.0
-
get
public T get() throws ConcurrentException
Returns the object wrapped by this instance. On first access the object is created. After that it is cached and can be accessed pretty fast.- Returns:
- the object initialized by this
LazyInitializer
- Throws:
ConcurrentException
- if an error occurred during initialization of the object
-
getTypedException
protected ConcurrentException getTypedException(java.lang.Exception e)
Gets an Exception with a type of E as defined by a concrete subclass of this class.- Specified by:
getTypedException
in classAbstractConcurrentInitializer<T,ConcurrentException>
- Parameters:
e
- The actual exception that was thrown- Returns:
- a new exception with the actual type of E, that wraps e.
-
isInitialized
public boolean isInitialized()
Tests whether this instance is initialized. Once initialized, always returns true.- Specified by:
isInitialized
in classAbstractConcurrentInitializer<T,ConcurrentException>
- Returns:
- whether this instance is initialized. Once initialized, always returns true.
- Since:
- 3.14.0
-
-