Package org.apache.commons.lang3.concurrent

# Class MultiBackgroundInitializer

java.lang.Object
org.apache.commons.lang3.concurrent.AbstractConcurrentInitializer<MultiBackgroundInitializer.MultiBackgroundInitializerResults,Exception>
org.apache.commons.lang3.concurrent.BackgroundInitializer<MultiBackgroundInitializer.MultiBackgroundInitializerResults>
org.apache.commons.lang3.concurrent.MultiBackgroundInitializer

All Implemented Interfaces:
  `ConcurrentInitializer<MultiBackgroundInitializer.MultiBackgroundInitializerResults>`, `FailableSupplier<MultiBackgroundInitializer.MultiBackgroundInitializerResults,ConcurrentException>`

public class MultiBackgroundInitializer extends BackgroundInitializer<MultiBackgroundInitializer.MultiBackgroundInitializerResults>
A specialized `BackgroundInitializer` implementation that can deal with multiple background initialization tasks.

This class has a similar purpose as `BackgroundInitializer`. However, it is not limited to a single background initialization task. Rather it manages an arbitrary number of `BackgroundInitializer` objects, executes them, and waits until they are completely initialized. This is useful for applications that have to perform multiple initialization tasks that can run in parallel (i.e. that do not depend on each other). This class takes care about the management of an `ExecutorService` and shares it with the `BackgroundInitializer` objects it is responsible for; so the using application need not bother with these details.

The typical usage scenario for `MultiBackgroundInitializer` is as follows:

- Create a new instance of the class. Optionally pass in a pre-configured `ExecutorService`. Alternatively `MultiBackgroundInitializer` can create a temporary `ExecutorService` and delete it after initialization is complete.
- Create specialized `BackgroundInitializer` objects for the initialization tasks to be performed and add them to the `MultiBackgroundInitializer` using the `addInitializer(String, BackgroundInitializer)` method.
- After all initializers have been added, call the `BackgroundInitializer.start()` method.
- When access to the result objects produced by the `BackgroundInitializer` objects is needed call the `BackgroundInitializer.get()` method. The object returned here provides access to all result objects created during initialization. It also stores information about exceptions that have occurred.

`MultiBackgroundInitializer` starts a special controller task that starts all `BackgroundInitializer` objects added to the instance. Before the an initializer is started it is checked whether this initializer already has an `ExecutorService` set. If this is the case, this `ExecutorService` is used for running the background task. Otherwise the current `ExecutorService` of this `MultiBackgroundInitializer` is shared with the initializer.

The easiest way of using this class is to let it deal with the management of an `ExecutorService` itself: If no external `ExecutorService` is provided, the class creates a temporary `ExecutorService` (that is capable of executing all background tasks in parallel) and destroys it at the end of background processing.

Alternatively an external `ExecutorService` can be provided - either at construction time or later by calling the `BackgroundInitializer.setExternalExecutor(ExecutorService)` method. In this case all background tasks are scheduled at this external `ExecutorService`. Important note: When using an external `ExecutorService` be sure that the number of threads managed by the service is large enough. Otherwise a deadlock can happen! This is the case in the following scenario: `MultiBackgroundInitializer` starts a task that starts all registered `BackgroundInitializer` objects and waits for their completion. If for instance a single threaded `ExecutorService` is used, none of the background tasks can be executed, and the task created by `MultiBackgroundInitializer` waits forever.

Since:
  3.0

- ## Nested Class Summary

  Nested Classes
  Modifier and Type
  Class
  Description
  `static class`
  `MultiBackgroundInitializer.MultiBackgroundInitializerResults`
  A data class for storing the results of the background initialization performed by `MultiBackgroundInitializer`.

  ## Nested classes/interfaces inherited from class org.apache.commons.lang3.concurrent.BackgroundInitializer

  `BackgroundInitializer.Builder<I extends BackgroundInitializer<T>,T>`

  ## 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 Exception>`

- ## Field Summary

  ### Fields inherited from interface org.apache.commons.lang3.function.FailableSupplier

  `NUL`

- ## Constructor Summary

  Constructors
  Constructor
  Description
  `MultiBackgroundInitializer()`
  Constructs a new instance of `MultiBackgroundInitializer`.
  `MultiBackgroundInitializer(ExecutorService exec)`
  Constructs a new instance of `MultiBackgroundInitializer` and initializes it with the given external `ExecutorService`.

- ## Method Summary

  Modifier and Type
  Method
  Description
  `void`
  `addInitializer(String name, BackgroundInitializer<?> backgroundInitializer)`
  Adds a new `BackgroundInitializer` to this object.
  `void`
  `close()`
  Calls the closer of all child `BackgroundInitializer` objects
  `protected int`
  `getTaskCount()`
  Gets the number of tasks needed for executing all child `BackgroundInitializer` objects in parallel.
  `protected MultiBackgroundInitializer.MultiBackgroundInitializerResults`
  `initialize()`
  Creates the results object.
  `boolean`
  `isInitialized()`
  Tests whether this all child `BackgroundInitializer` objects are initialized.

  ### Methods inherited from class org.apache.commons.lang3.concurrent.BackgroundInitializer

  `builder, get, getActiveExecutor, getExternalExecutor, getFuture, getTypedException, isStarted, setExternalExecutor, start`

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

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

- ## Constructor Details

  - ### MultiBackgroundInitializer

    public MultiBackgroundInitializer()
    Constructs a new instance of `MultiBackgroundInitializer`.

  - ### MultiBackgroundInitializer

    public MultiBackgroundInitializer(ExecutorService exec)
    Constructs a new instance of `MultiBackgroundInitializer` and initializes it with the given external `ExecutorService`.
    Parameters:
      `exec` - the `ExecutorService` for executing the background tasks

- ## Method Details

  - ### addInitializer

    public void addInitializer(String name, BackgroundInitializer<?> backgroundInitializer)
    Adds a new `BackgroundInitializer` to this object. When this `MultiBackgroundInitializer` is started, the given initializer will be processed. This method must not be called after `BackgroundInitializer.start()` has been invoked.
    Parameters:
      `name` - the name of the initializer (must not be null)
      `backgroundInitializer` - the `BackgroundInitializer` to add (must not be null)
    Throws:
      `NullPointerException` - if either `name` or `backgroundInitializer` is `null`
      `IllegalStateException` - if `start()` has already been called

  - ### close

    public void close() throws ConcurrentException
    Calls the closer of all child `BackgroundInitializer` objects
    Overrides:
      `close` in class `AbstractConcurrentInitializer<MultiBackgroundInitializer.MultiBackgroundInitializerResults,Exception>`
    Throws:
      `ConcurrentException` - throws an ConcurrentException that will have all other exceptions as suppressed exceptions. ConcurrentException thrown by children will be unwrapped.
    Since:
      3.14.0

  - ### getTaskCount

    protected int getTaskCount()
    Gets the number of tasks needed for executing all child `BackgroundInitializer` objects in parallel. This implementation sums up the required tasks for all child initializers (which is necessary if one of the child initializers is itself a `MultiBackgroundInitializer` ). Then it adds 1 for the control task that waits for the completion of the children.
    Overrides:
      `getTaskCount` in class `BackgroundInitializer<MultiBackgroundInitializer.MultiBackgroundInitializerResults>`
    Returns:
      the number of tasks required for background processing

  - ### initialize

    protected MultiBackgroundInitializer.MultiBackgroundInitializerResults initialize() throws Exception
    Creates the results object. This implementation starts all child `BackgroundInitializer` objects. Then it collects their results and creates a `MultiBackgroundInitializer.MultiBackgroundInitializerResults` object with this data. If a child initializer throws a checked exceptions, it is added to the results object. Unchecked exceptions are propagated.
    Overrides:
      `initialize` in class `AbstractConcurrentInitializer<MultiBackgroundInitializer.MultiBackgroundInitializerResults,Exception>`
    Returns:
      the results object
    Throws:
      `Exception` - if an error occurs

  - ### isInitialized

    public boolean isInitialized()
    Tests whether this all child `BackgroundInitializer` objects are initialized. Once initialized, always returns true.
    Overrides:
      `isInitialized` in class `BackgroundInitializer<MultiBackgroundInitializer.MultiBackgroundInitializerResults>`
    Returns:
      whether all child `BackgroundInitializer` objects instance are initialized. Once initialized, always returns true. If there are no child `BackgroundInitializer` objects return false.
    Since:
      3.14.0