AtomicInitializer (Apache Commons Lang 3.20.0 API)
Description: declaration: package: org.apache.commons.lang3.concurrent, class: AtomicInitializer

# Class AtomicInitializer<T>

java.lang.Object
org.apache.commons.lang3.concurrent.AbstractConcurrentInitializer<T, ConcurrentException>
org.apache.commons.lang3.concurrent.AtomicInitializer<T>

Type Parameters:
  `T` - the type of the object managed by this initializer class.

All Implemented Interfaces:
  `ConcurrentInitializer<T>, FailableSupplier<T, ConcurrentException>`

public class AtomicInitializer<T> extends AbstractConcurrentInitializer<T, ConcurrentException>
A specialized implementation of the `ConcurrentInitializer` interface based on an `AtomicReference` variable.

This class maintains a member field of type `AtomicReference`. It implements the following algorithm to create and initialize an object in its `get()` method:

- First it is checked whether the `AtomicReference` variable contains already a value. If this is the case, the value is directly returned.
- Otherwise the `AbstractConcurrentInitializer.initialize()` method is called. This method must be defined in concrete subclasses to actually create the managed object.
- After the object was created by `AbstractConcurrentInitializer.initialize()` it is checked whether the `AtomicReference` variable is still undefined. This has to be 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 `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 `AtomicInitializer` object before it has been initialized almost at the same time, it can happen that `AbstractConcurrentInitializer.initialize()` is called multiple times. The algorithm outlined above guarantees that `get()` always returns the same object though.

Compared with the `LazyInitializer` class, this class can be more efficient because it does not need synchronization. The drawback is that the `AbstractConcurrentInitializer.initialize()` method can be called multiple times which may be problematic 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, `LazyInitializer` is more appropriate.

Since:
  3.0

- ## Nested Class Summary

  Nested Classes
  Modifier and Type
  Class
  Description
  `static class`
  `AtomicInitializer.Builder<I extends AtomicInitializer<T>, T>`
  Builds a new instance.

  ### Nested classes/interfaces inherited from class AbstractConcurrentInitializer

  `AbstractConcurrentInitializer.AbstractBuilder<I,T,B,E>`

- ## Field Summary

  ### Fields inherited from interface FailableSupplier

  `NUL`

- ## Constructor Summary

  Constructors
  Constructor
  Description
  `AtomicInitializer()`
  Constructs a new instance.

- ## Method Summary

  Modifier and Type
  Method
  Description
  `static <T> AtomicInitializer.Builder<AtomicInitializer<T>, T>`
  `builder()`
  Creates a new builder.
  `T`
  `get()`
  Gets the object managed by this initializer.
  `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.

  ### Methods inherited from class AbstractConcurrentInitializer

  `close, initialize`

  ### Methods inherited from class Object

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

- ## Constructor Details

  - ### AtomicInitializer

    public AtomicInitializer()
    Constructs a new instance.

- ## Method Details

  - ### builder

    public static <T> AtomicInitializer.Builder<AtomicInitializer<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
    Gets the object managed by this initializer. The object is created if it is not available yet and stored internally. This method always returns the same object.
    Returns:
      the object created by this `AtomicInitializer`.
    Throws:
      `ConcurrentException` - if an error occurred during initialization of the object.

  - ### getTypedException

    protected ConcurrentException getTypedException(Exception e)
    Gets an Exception with a type of E as defined by a concrete subclass of this class.
    Specified by:
      `getTypedException` in class `AbstractConcurrentInitializer<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 class `AbstractConcurrentInitializer<T, ConcurrentException>`
    Returns:
      whether this instance is initialized. Once initialized, always returns true.
    Since:
      3.14.0