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