T
- the type of the object managed by the initializer.public class LazyInitializer<T> extends AbstractConcurrentInitializer<T,ConcurrentException>
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 |
---|---|
static class |
LazyInitializer.Builder<I extends LazyInitializer<T>,T>
Builds a new instance.
|
AbstractConcurrentInitializer.AbstractBuilder<I extends AbstractConcurrentInitializer<T,E>,T,B extends AbstractConcurrentInitializer.AbstractBuilder<I,T,B,E>,E extends Exception>
NUL
Constructor and Description |
---|
LazyInitializer()
Constructs a new instance.
|
Modifier and Type | Method and 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(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.
|
close, initialize
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
nul
public LazyInitializer()
public static <T> LazyInitializer.Builder<LazyInitializer<T>,T> builder()
T
- the type of object to build.public T get() throws ConcurrentException
LazyInitializer
ConcurrentException
- if an error occurred during initialization of the objectprotected ConcurrentException getTypedException(Exception e)
getTypedException
in class AbstractConcurrentInitializer<T,ConcurrentException>
e
- The actual exception that was thrownpublic boolean isInitialized()
isInitialized
in class AbstractConcurrentInitializer<T,ConcurrentException>
Copyright © 2001–2023 The Apache Software Foundation. All rights reserved.