View Javadoc
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  
19  import java.util.concurrent.Callable;
20  import java.util.concurrent.ExecutorService;
21  
22  /**
23   * <p>
24   * A specialized {@link BackgroundInitializer} implementation that wraps a
25   * {@code Callable} object.
26   * </p>
27   * <p>
28   * An instance of this class is initialized with a {@code Callable} object when
29   * it is constructed. The implementation of the {@link #initialize()} method
30   * defined in the super class delegates to this {@code Callable} so that the
31   * {@code Callable} is executed in the background thread.
32   * </p>
33   * <p>
34   * The {@code java.util.concurrent.Callable} interface is a standard mechanism
35   * of the JDK to define tasks to be executed by another thread. The {@code
36   * CallableBackgroundInitializer} class allows combining this standard interface
37   * with the background initializer API.
38   * </p>
39   * <p>
40   * Usage of this class is very similar to the default usage pattern of the
41   * {@link BackgroundInitializer} class: Just create an instance and provide the
42   * {@code Callable} object to be executed, then call the initializer's
43   * {@link #start()} method. This causes the {@code Callable} to be executed in
44   * another thread. When the results of the {@code Callable} are needed the
45   * initializer's {@link #get()} method can be called (which may block until
46   * background execution is complete). The following code fragment shows a
47   * typical usage example:
48   * </p>
49   *
50   * <pre>
51   * // a Callable that performs a complex computation
52   * Callable&lt;Integer&gt; computationCallable = new MyComputationCallable();
53   * // setup the background initializer
54   * CallableBackgroundInitializer&lt;Integer&gt; initializer =
55   *     new CallableBackgroundInitializer(computationCallable);
56   * initializer.start();
57   * // Now do some other things. Initialization runs in a parallel thread
58   * ...
59   * // Wait for the end of initialization and access the result
60   * Integer result = initializer.get();
61   * </pre>
62   *
63   *
64   * @since 3.0
65   * @version $Id: CallableBackgroundInitializer.java 1583482 2014-03-31 22:54:57Z niallp $
66   * @param <T> the type of the object managed by this initializer class
67   */
68  public class CallableBackgroundInitializer<T> extends BackgroundInitializer<T> {
69      /** The Callable to be executed. */
70      private final Callable<T> callable;
71  
72      /**
73       * Creates a new instance of {@code CallableBackgroundInitializer} and sets
74       * the {@code Callable} to be executed in a background thread.
75       *
76       * @param call the {@code Callable} (must not be <b>null</b>)
77       * @throws IllegalArgumentException if the {@code Callable} is <b>null</b>
78       */
79      public CallableBackgroundInitializer(final Callable<T> call) {
80          checkCallable(call);
81          callable = call;
82      }
83  
84      /**
85       * Creates a new instance of {@code CallableBackgroundInitializer} and
86       * initializes it with the {@code Callable} to be executed in a background
87       * thread and the {@code ExecutorService} for managing the background
88       * execution.
89       *
90       * @param call the {@code Callable} (must not be <b>null</b>)
91       * @param exec an external {@code ExecutorService} to be used for task
92       * execution
93       * @throws IllegalArgumentException if the {@code Callable} is <b>null</b>
94       */
95      public CallableBackgroundInitializer(final Callable<T> call, final ExecutorService exec) {
96          super(exec);
97          checkCallable(call);
98          callable = call;
99      }
100 
101     /**
102      * Performs initialization in a background thread. This implementation
103      * delegates to the {@code Callable} passed at construction time of this
104      * object.
105      *
106      * @return the result of the initialization
107      * @throws Exception if an error occurs
108      */
109     @Override
110     protected T initialize() throws Exception {
111         return callable.call();
112     }
113 
114     /**
115      * Tests the passed in {@code Callable} and throws an exception if it is
116      * undefined.
117      *
118      * @param call the object to check
119      * @throws IllegalArgumentException if the {@code Callable} is <b>null</b>
120      */
121     private void checkCallable(final Callable<T> call) {
122         if (call == null) {
123             throw new IllegalArgumentException("Callable must not be null!");
124         }
125     }
126 }