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 of LazyInitializer 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 the ComplexObject 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 the get()
method are pretty fast because no synchronization is needed (only an access to a volatile member field).
| Modifier and Type | Class and Description |
|---|---|
| public static class | LazyInitializer.
The type of the initializer managed by this builder. I extends LazyInitializerThe type of results supplied by this builder. T>Builds a new instance. |
| Modifier and Type | Field and Description |
|---|---|
| private static final Object | NO_INIT
A unique value indicating an un-initialized instance. |
| private volatile T | object
Stores the managed object. |
| Access | Constructor and Description |
|---|---|
| public | |
| private | LazyInitializer(final FailableSupplier<T, ConcurrentException>
the initializer supplier called by initializer, final FailableConsumer<T, ConcurrentException> initialize().the closer consumer called by closer)close().Constructs a new instance. |
| Modifier and Type | Method and Description |
|---|---|
| public static < the type of object to build. T> LazyInitializer. | |
| public T | Returns: the object initialized by thisLazyInitializer.Implements org. Gets the object wrapped by this instance. |
| protected ConcurrentException | getTypedException(final Exception e)
Implements abstract org. Gets an Exception with a type of E as defined by a concrete subclass of this class. |
| public boolean | Returns: whether this instance is initialized. Once initialized, always returns true.Implements abstract org. Tests whether this instance is initialized. |
| NO_INIT | back to summary |
|---|---|
| private static final Object NO_INIT A unique value indicating an un-initialized instance. | |
| object | back to summary |
|---|---|
| private volatile T object Stores the managed object.
| |
| LazyInitializer | back to summary |
|---|---|
| public LazyInitializer() Constructs a new instance. | |
| LazyInitializer | back to summary |
|---|---|
| private LazyInitializer(final FailableSupplier<T, ConcurrentException> initializer, final FailableConsumer<T, ConcurrentException> closer) Constructs a new instance.
| |
| builder | back to summary |
|---|---|
| public static <T> LazyInitializer. Creates a new builder.
| |
| get | back to summary |
|---|---|
| public T get() throws ConcurrentException Implements org. Gets the object wrapped by this instance. On first access the object is created. After that it is cached and can be accessed pretty fast.
| |
| getTypedException | back to summary |
|---|---|
| protected ConcurrentException getTypedException(final Exception e) Implements abstract org. Doc from org. Gets an Exception with a type of E as defined by a concrete subclass of this class.
| |
| isInitialized | back to summary |
|---|---|
| public boolean isInitialized() Implements abstract org. Tests whether this instance is initialized. Once initialized, always returns true.
| |
| Access | Constructor and Description |
|---|---|
| public |
| Modifier and Type | Method and Description |
|---|---|
| public I |
| Builder | back to summary |
|---|---|
| public Builder() Constructs a new instance. | |
| get | back to summary |
|---|---|
| public I get() Implements org. Doc from org. Supplies an object
| |