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 022/** 023 * <p> 024 * A specialized {@link BackgroundInitializer} implementation that wraps a 025 * {@code Callable} object. 026 * </p> 027 * <p> 028 * An instance of this class is initialized with a {@code Callable} object when 029 * it is constructed. The implementation of the {@link #initialize()} method 030 * defined in the super class delegates to this {@code Callable} so that the 031 * {@code Callable} is executed in the background thread. 032 * </p> 033 * <p> 034 * The {@code java.util.concurrent.Callable} interface is a standard mechanism 035 * of the JDK to define tasks to be executed by another thread. The {@code 036 * CallableBackgroundInitializer} class allows combining this standard interface 037 * with the background initializer API. 038 * </p> 039 * <p> 040 * Usage of this class is very similar to the default usage pattern of the 041 * {@link BackgroundInitializer} class: Just create an instance and provide the 042 * {@code Callable} object to be executed, then call the initializer's 043 * {@link #start()} method. This causes the {@code Callable} to be executed in 044 * another thread. When the results of the {@code Callable} are needed the 045 * initializer's {@link #get()} method can be called (which may block until 046 * background execution is complete). The following code fragment shows a 047 * typical usage example: 048 * </p> 049 * 050 * <pre> 051 * // a Callable that performs a complex computation 052 * Callable<Integer> computationCallable = new MyComputationCallable(); 053 * // setup the background initializer 054 * CallableBackgroundInitializer<Integer> initializer = 055 * new CallableBackgroundInitializer(computationCallable); 056 * initializer.start(); 057 * // Now do some other things. Initialization runs in a parallel thread 058 * ... 059 * // Wait for the end of initialization and access the result 060 * Integer result = initializer.get(); 061 * </pre> 062 * 063 * 064 * @since 3.0 065 * @param <T> the type of the object managed by this initializer class 066 */ 067public class CallableBackgroundInitializer<T> extends BackgroundInitializer<T> { 068 /** The Callable to be executed. */ 069 private final Callable<T> callable; 070 071 /** 072 * Creates a new instance of {@code CallableBackgroundInitializer} and sets 073 * the {@code Callable} to be executed in a background thread. 074 * 075 * @param call the {@code Callable} (must not be <b>null</b>) 076 * @throws IllegalArgumentException if the {@code Callable} is <b>null</b> 077 */ 078 public CallableBackgroundInitializer(final Callable<T> call) { 079 checkCallable(call); 080 callable = call; 081 } 082 083 /** 084 * Creates a new instance of {@code CallableBackgroundInitializer} and 085 * initializes it with the {@code Callable} to be executed in a background 086 * thread and the {@code ExecutorService} for managing the background 087 * execution. 088 * 089 * @param call the {@code Callable} (must not be <b>null</b>) 090 * @param exec an external {@code ExecutorService} to be used for task 091 * execution 092 * @throws IllegalArgumentException if the {@code Callable} is <b>null</b> 093 */ 094 public CallableBackgroundInitializer(final Callable<T> call, final ExecutorService exec) { 095 super(exec); 096 checkCallable(call); 097 callable = call; 098 } 099 100 /** 101 * Performs initialization in a background thread. This implementation 102 * delegates to the {@code Callable} passed at construction time of this 103 * object. 104 * 105 * @return the result of the initialization 106 * @throws Exception if an error occurs 107 */ 108 @Override 109 protected T initialize() throws Exception { 110 return callable.call(); 111 } 112 113 /** 114 * Tests the passed in {@code Callable} and throws an exception if it is 115 * undefined. 116 * 117 * @param call the object to check 118 * @throws IllegalArgumentException if the {@code Callable} is <b>null</b> 119 */ 120 private void checkCallable(final Callable<T> call) { 121 if (call == null) { 122 throw new IllegalArgumentException("Callable must not be null!"); 123 } 124 } 125}