001/* 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017package org.apache.commons.lang3.concurrent; 018 019import java.util.concurrent.Callable; 020import java.util.concurrent.ExecutorService; 021 022import org.apache.commons.lang3.Validate; 023 024/** 025 * <p> 026 * A specialized {@link BackgroundInitializer} implementation that wraps a 027 * {@code Callable} object. 028 * </p> 029 * <p> 030 * An instance of this class is initialized with a {@code Callable} object when 031 * it is constructed. The implementation of the {@link #initialize()} method 032 * defined in the super class delegates to this {@code Callable} so that the 033 * {@code Callable} is executed in the background thread. 034 * </p> 035 * <p> 036 * The {@code java.util.concurrent.Callable} interface is a standard mechanism 037 * of the JDK to define tasks to be executed by another thread. The {@code 038 * CallableBackgroundInitializer} class allows combining this standard interface 039 * with the background initializer API. 040 * </p> 041 * <p> 042 * Usage of this class is very similar to the default usage pattern of the 043 * {@link BackgroundInitializer} class: Just create an instance and provide the 044 * {@code Callable} object to be executed, then call the initializer's 045 * {@link #start()} method. This causes the {@code Callable} to be executed in 046 * another thread. When the results of the {@code Callable} are needed the 047 * initializer's {@link #get()} method can be called (which may block until 048 * background execution is complete). The following code fragment shows a 049 * typical usage example: 050 * </p> 051 * 052 * <pre> 053 * // a Callable that performs a complex computation 054 * Callable<Integer> computationCallable = new MyComputationCallable(); 055 * // setup the background initializer 056 * CallableBackgroundInitializer<Integer> initializer = 057 * new CallableBackgroundInitializer(computationCallable); 058 * initializer.start(); 059 * // Now do some other things. Initialization runs in a parallel thread 060 * ... 061 * // Wait for the end of initialization and access the result 062 * Integer result = initializer.get(); 063 * </pre> 064 * 065 * 066 * @since 3.0 067 * @param <T> the type of the object managed by this initializer class 068 */ 069public class CallableBackgroundInitializer<T> extends BackgroundInitializer<T> { 070 /** The Callable to be executed. */ 071 private final Callable<T> callable; 072 073 /** 074 * Creates a new instance of {@code CallableBackgroundInitializer} and sets 075 * the {@code Callable} to be executed in a background thread. 076 * 077 * @param call the {@code Callable} (must not be <b>null</b>) 078 * @throws IllegalArgumentException if the {@code Callable} is <b>null</b> 079 */ 080 public CallableBackgroundInitializer(final Callable<T> call) { 081 checkCallable(call); 082 callable = call; 083 } 084 085 /** 086 * Creates a new instance of {@code CallableBackgroundInitializer} and 087 * initializes it with the {@code Callable} to be executed in a background 088 * thread and the {@code ExecutorService} for managing the background 089 * execution. 090 * 091 * @param call the {@code Callable} (must not be <b>null</b>) 092 * @param exec an external {@code ExecutorService} to be used for task 093 * execution 094 * @throws IllegalArgumentException if the {@code Callable} is <b>null</b> 095 */ 096 public CallableBackgroundInitializer(final Callable<T> call, final ExecutorService exec) { 097 super(exec); 098 checkCallable(call); 099 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}