Class BackgroundInitializer<T>

  • Type Parameters:
    T - the type of the object managed by this initializer class
    All Implemented Interfaces:
    ConcurrentInitializer<T>
    Direct Known Subclasses:
    CallableBackgroundInitializer, MultiBackgroundInitializer

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

    A class that allows complex initialization operations in a background task.

    Applications often have to do some expensive initialization steps when they are started, e.g. constructing a connection to a database, reading a configuration file, etc. Doing these things in parallel can enhance performance as the CPU load can be improved. However, when access to the resources initialized in a background thread is actually required, synchronization has to be performed to ensure that their initialization is complete.

    This abstract base class provides support for this use case. A concrete subclass must implement the initialize() method. Here an arbitrary initialization can be implemented, and a result object can be returned. With this method in place the basic usage of this class is as follows (where MyBackgroundInitializer is a concrete subclass):

     MyBackgroundInitializer initializer = new MyBackgroundInitializer();
     initializer.start();
     // Now do some other things. Initialization runs in a parallel thread
     ...
     // Wait for the end of initialization and access the result object
     Object result = initializer.get();
     

    After the construction of a BackgroundInitializer object its start() method has to be called. This starts the background processing. The application can now continue to do other things. When it needs access to the object produced by the BackgroundInitializer it calls its get() method. If initialization is already complete, get() returns the result object immediately. Otherwise it blocks until the result object is fully constructed.

    BackgroundInitializer is a thin wrapper around a Future object and uses an ExecutorService for running the background initialization task. It is possible to pass in an ExecutorService at construction time or set one using setExternalExecutor() before start() was called. Then this object is used to spawn the background task. If no ExecutorService has been provided, BackgroundInitializer creates a temporary ExecutorService and destroys it when initialization is complete.

    The methods provided by BackgroundInitializer provide for minimal interaction with the wrapped Future object. It is also possible to obtain the Future object directly. Then the enhanced functionality offered by Future can be used, e.g. to check whether the background operation is complete or to cancel the operation.

    Since:
    3.0
    • Constructor Summary

      Constructors 
      Modifier Constructor Description
      protected BackgroundInitializer()
      Creates a new instance of BackgroundInitializer.
      protected BackgroundInitializer​(java.util.concurrent.ExecutorService exec)
      Creates a new instance of BackgroundInitializer and initializes it with the given ExecutorService.
    • Method Summary

      All Methods Instance Methods Abstract Methods Concrete Methods 
      Modifier and Type Method Description
      T get()
      Returns the result of the background initialization.
      protected java.util.concurrent.ExecutorService getActiveExecutor()
      Returns the ExecutorService that is actually used for executing the background task.
      java.util.concurrent.ExecutorService getExternalExecutor()
      Returns the external ExecutorService to be used by this class.
      java.util.concurrent.Future<T> getFuture()
      Returns the Future object that was created when start() was called.
      protected int getTaskCount()
      Returns the number of background tasks to be created for this initializer.
      protected abstract T initialize()
      Performs the initialization.
      boolean isStarted()
      Returns a flag whether this BackgroundInitializer has already been started.
      void setExternalExecutor​(java.util.concurrent.ExecutorService externalExecutor)
      Sets an ExecutorService to be used by this class.
      boolean start()
      Starts the background initialization.
      • Methods inherited from class java.lang.Object

        clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
    • Constructor Detail

      • BackgroundInitializer

        protected BackgroundInitializer()
        Creates a new instance of BackgroundInitializer. No external ExecutorService is used.
      • BackgroundInitializer

        protected BackgroundInitializer​(java.util.concurrent.ExecutorService exec)
        Creates a new instance of BackgroundInitializer and initializes it with the given ExecutorService. If the ExecutorService is not null, the background task for initializing this object will be scheduled at this service. Otherwise a new temporary ExecutorService is created.
        Parameters:
        exec - an external ExecutorService to be used for task execution
    • Method Detail

      • getExternalExecutor

        public final java.util.concurrent.ExecutorService getExternalExecutor()
        Returns the external ExecutorService to be used by this class.
        Returns:
        the ExecutorService
      • isStarted

        public boolean isStarted()
        Returns a flag whether this BackgroundInitializer has already been started.
        Returns:
        a flag whether the start() method has already been called
      • setExternalExecutor

        public final void setExternalExecutor​(java.util.concurrent.ExecutorService externalExecutor)
        Sets an ExecutorService to be used by this class. The ExecutorService passed to this method is used for executing the background task. Thus it is possible to re-use an already existing ExecutorService or to use a specially configured one. If no ExecutorService is set, this instance creates a temporary one and destroys it after background initialization is complete. Note that this method must be called before start(); otherwise an exception is thrown.
        Parameters:
        externalExecutor - the ExecutorService to be used
        Throws:
        java.lang.IllegalStateException - if this initializer has already been started
      • start

        public boolean start()
        Starts the background initialization. With this method the initializer becomes active and invokes the initialize() method in a background task. A BackgroundInitializer can be started exactly once. The return value of this method determines whether the start was successful: only the first invocation of this method returns true, following invocations will return false.
        Returns:
        a flag whether the initializer could be started successfully
      • get

        public T get()
              throws ConcurrentException
        Returns the result of the background initialization. This method blocks until initialization is complete. If the background processing caused a runtime exception, it is directly thrown by this method. Checked exceptions, including InterruptedException are wrapped in a ConcurrentException. Calling this method before start() was called causes an IllegalStateException exception to be thrown.
        Specified by:
        get in interface ConcurrentInitializer<T>
        Returns:
        the object produced by this initializer
        Throws:
        ConcurrentException - if a checked exception occurred during background processing
        java.lang.IllegalStateException - if start() has not been called
      • getFuture

        public java.util.concurrent.Future<T> getFuture()
        Returns the Future object that was created when start() was called. Therefore this method can only be called after start().
        Returns:
        the Future object wrapped by this initializer
        Throws:
        java.lang.IllegalStateException - if start() has not been called
      • getActiveExecutor

        protected final java.util.concurrent.ExecutorService getActiveExecutor()
        Returns the ExecutorService that is actually used for executing the background task. This method can be called after start() (before start() it returns null). If an external executor was set, this is also the active executor. Otherwise this method returns the temporary executor that was created by this object.
        Returns:
        the ExecutorService for executing the background task
      • getTaskCount

        protected int getTaskCount()
        Returns the number of background tasks to be created for this initializer. This information is evaluated when a temporary ExecutorService is created. This base implementation returns 1. Derived classes that do more complex background processing can override it. This method is called from a synchronized block by the start() method. Therefore overriding methods should be careful with obtaining other locks and return as fast as possible.
        Returns:
        the number of background tasks required by this initializer
      • initialize

        protected abstract T initialize()
                                 throws java.lang.Exception
        Performs the initialization. This method is called in a background task when this BackgroundInitializer is started. It must be implemented by a concrete subclass. An implementation is free to perform arbitrary initialization. The object returned by this method can be queried using the get() method.
        Returns:
        a result object
        Throws:
        java.lang.Exception - if an error occurs