MultiBackgroundInitializer
Date: 2017-02-08

org.apache.commons.lang3.concurrent

## Class MultiBackgroundInitializer

- java.lang.Object
- - org.apache.commons.lang3.concurrent.BackgroundInitializer<MultiBackgroundInitializer.MultiBackgroundInitializerResults>
  - - org.apache.commons.lang3.concurrent.MultiBackgroundInitializer

- All Implemented Interfaces:
    ConcurrentInitializer<MultiBackgroundInitializer.MultiBackgroundInitializerResults>

      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 and Description
    --- | ---
    `static class` | `MultiBackgroundInitializer.MultiBackgroundInitializerResults` A data class for storing the results of the background initialization performed by `MultiBackgroundInitializer`.

  - ### Constructor Summary

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

  - ### Method Summary

    Methods
    Modifier and Type | Method and Description
    --- | ---
    `void` | `addInitializer(java.lang.String name, BackgroundInitializer<?> init)` Adds a new `BackgroundInitializer` to this object.
    `protected int` | `getTaskCount()` Returns the number of tasks needed for executing all child `BackgroundInitializer` objects in parallel.
    `protected MultiBackgroundInitializer.MultiBackgroundInitializerResults` | `initialize()` Creates the results object.

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

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

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

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

- - ### Constructor Detail

    - #### MultiBackgroundInitializer

          public MultiBackgroundInitializer()

      Creates a new instance of `MultiBackgroundInitializer`.

    - #### MultiBackgroundInitializer

          public MultiBackgroundInitializer(java.util.concurrent.ExecutorService exec)

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

  - ### Method Detail

    - #### addInitializer

          public void addInitializer(java.lang.String name,
                            BackgroundInitializer<?> init)

      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)
        `init` - the `BackgroundInitializer` to add (must not be null)
      Throws:
        `java.lang.IllegalArgumentException` - if a required parameter is missing
        `java.lang.IllegalStateException` - if `start()` has already been called

    - #### getTaskCount

          protected int getTaskCount()

      Returns 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 java.lang.Exception

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