CallableBackgroundInitializer.java

  1. /*
  2.  * Licensed to the Apache Software Foundation (ASF) under one or more
  3.  * contributor license agreements.  See the NOTICE file distributed with
  4.  * this work for additional information regarding copyright ownership.
  5.  * The ASF licenses this file to You under the Apache License, Version 2.0
  6.  * (the "License"); you may not use this file except in compliance with
  7.  * the License.  You may obtain a copy of the License at
  8.  *
  9.  *      http://www.apache.org/licenses/LICENSE-2.0
  10.  *
  11.  * Unless required by applicable law or agreed to in writing, software
  12.  * distributed under the License is distributed on an "AS IS" BASIS,
  13.  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14.  * See the License for the specific language governing permissions and
  15.  * limitations under the License.
  16.  */
  17. package org.apache.commons.lang3.concurrent;

  18. import java.util.Objects;
  19. import java.util.concurrent.Callable;
  20. import java.util.concurrent.ExecutorService;

  21. /**
  22.  * A specialized {@link BackgroundInitializer} implementation that wraps a
  23.  * {@link Callable} object.
  24.  *
  25.  * <p>
  26.  * An instance of this class is initialized with a {@link Callable} object when
  27.  * it is constructed. The implementation of the {@link #initialize()} method
  28.  * defined in the super class delegates to this {@link Callable} so that the
  29.  * {@link Callable} is executed in the background thread.
  30.  * </p>
  31.  * <p>
  32.  * The {@link java.util.concurrent.Callable} interface is a standard mechanism
  33.  * of the JDK to define tasks to be executed by another thread. The {@code
  34.  * CallableBackgroundInitializer} class allows combining this standard interface
  35.  * with the background initializer API.
  36.  * </p>
  37.  * <p>
  38.  * Usage of this class is very similar to the default usage pattern of the
  39.  * {@link BackgroundInitializer} class: Just create an instance and provide the
  40.  * {@link Callable} object to be executed, then call the initializer's
  41.  * {@link #start()} method. This causes the {@link Callable} to be executed in
  42.  * another thread. When the results of the {@link Callable} are needed the
  43.  * initializer's {@link #get()} method can be called (which may block until
  44.  * background execution is complete). The following code fragment shows a
  45.  * typical usage example:
  46.  * </p>
  47.  *
  48.  * <pre>{@code
  49.  * // a Callable that performs a complex computation
  50.  * Callable<Integer> computationCallable = new MyComputationCallable();
  51.  * // setup the background initializer
  52.  * CallableBackgroundInitializer<Integer> initializer =
  53.  *     new CallableBackgroundInitializer(computationCallable);
  54.  * initializer.start();
  55.  * // Now do some other things. Initialization runs in a parallel thread
  56.  * ...
  57.  * // Wait for the end of initialization and access the result
  58.  * Integer result = initializer.get();
  59.  * }
  60.  * </pre>
  61.  *
  62.  * @since 3.0
  63.  * @param <T> the type of the object managed by this initializer class
  64.  */
  65. public class CallableBackgroundInitializer<T> extends BackgroundInitializer<T> {
  66.     /** The Callable to be executed. */
  67.     private final Callable<T> callable;

  68.     /**
  69.      * Creates a new instance of {@link CallableBackgroundInitializer} and sets
  70.      * the {@link Callable} to be executed in a background thread.
  71.      *
  72.      * @param call the {@link Callable} (must not be <b>null</b>)
  73.      * @throws IllegalArgumentException if the {@link Callable} is <b>null</b>
  74.      */
  75.     public CallableBackgroundInitializer(final Callable<T> call) {
  76.         checkCallable(call);
  77.         callable = call;
  78.     }

  79.     /**
  80.      * Creates a new instance of {@link CallableBackgroundInitializer} and
  81.      * initializes it with the {@link Callable} to be executed in a background
  82.      * thread and the {@link ExecutorService} for managing the background
  83.      * execution.
  84.      *
  85.      * @param call the {@link Callable} (must not be <b>null</b>)
  86.      * @param exec an external {@link ExecutorService} to be used for task
  87.      * execution
  88.      * @throws IllegalArgumentException if the {@link Callable} is <b>null</b>
  89.      */
  90.     public CallableBackgroundInitializer(final Callable<T> call, final ExecutorService exec) {
  91.         super(exec);
  92.         checkCallable(call);
  93.         callable = call;
  94.     }

  95.     /**
  96.      * Tests the passed in {@link Callable} and throws an exception if it is
  97.      * undefined.
  98.      *
  99.      * @param callable the object to check
  100.      * @throws IllegalArgumentException if the {@link Callable} is <b>null</b>
  101.      */
  102.     private void checkCallable(final Callable<T> callable) {
  103.         Objects.requireNonNull(callable, "callable");
  104.     }

  105.     /**
  106.      * {@inheritDoc}
  107.      */
  108.     @Override
  109.     protected Exception getTypedException(final Exception e) {
  110.         //This Exception object will be used for type comparison in AbstractConcurrentInitializer.initialize but not thrown
  111.         return new Exception(e);
  112.     }

  113.     /**
  114.      * Performs initialization in a background thread. This implementation
  115.      * delegates to the {@link Callable} passed at construction time of this
  116.      * object.
  117.      *
  118.      * @return the result of the initialization
  119.      * @throws Exception if an error occurs
  120.      */
  121.     @Override
  122.     protected T initialize() throws Exception {
  123.         return callable.call();
  124.     }
  125. }