LazyInitializer
Date: 2017-02-08

org.apache.commons.lang3.concurrent

## Class LazyInitializer<T>

- java.lang.Object
- - org.apache.commons.lang3.concurrent.LazyInitializer<T>

- Type Parameters:
    `T` - the type of the object managed by this initializer class
  All Implemented Interfaces:
    ConcurrentInitializer<T>

      public abstract class LazyInitializer<T>
      extends java.lang.Object
      implements ConcurrentInitializer<T>

  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 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).

  Since:
    3.0

- - ### Constructor Summary

    Constructors
    Constructor and Description
    `LazyInitializer()`

  - ### Method Summary

    Methods
    Modifier and Type | Method and Description
    --- | ---
    `T` | `get()` Returns the object wrapped by this instance.
    `protected abstract T` | `initialize()` Creates and initializes the object managed by this `LazyInitializer`.

    - ### Methods inherited from class java.lang.Object

      `clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait`

- - ### Constructor Detail

    - #### LazyInitializer

          public LazyInitializer()

  - ### Method Detail

    - #### 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.
      Specified by:
        `get` in interface `ConcurrentInitializer<T>`
      Returns:
        the object initialized by this `LazyInitializer`
      Throws:
        `ConcurrentException` - if an error occurred during initialization of the object

    - #### initialize

          protected abstract T initialize()
                                   throws ConcurrentException

      Creates and initializes the object managed by this `LazyInitializer`. This method is called by `get()` when the object is accessed for the first time. An implementation can focus on the creation of the object. No synchronization is needed, as this is already handled by `get()`.
      Returns:
        the managed data object
      Throws:
        `ConcurrentException` - if an error occurs during object creation