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 * @version $Id: CallableBackgroundInitializer.java 1583482 2014-03-31 22:54:57Z niallp $ 066 * @param <T> the type of the object managed by this initializer class 067 */ 068public class CallableBackgroundInitializer<T> extends BackgroundInitializer<T> { 069 /** The Callable to be executed. */ 070 private final Callable<T> callable; 071 072 /** 073 * Creates a new instance of {@code CallableBackgroundInitializer} and sets 074 * the {@code Callable} to be executed in a background thread. 075 * 076 * @param call the {@code Callable} (must not be <b>null</b>) 077 * @throws IllegalArgumentException if the {@code Callable} is <b>null</b> 078 */ 079 public CallableBackgroundInitializer(final Callable<T> call) { 080 checkCallable(call); 081 callable = call; 082 } 083 084 /** 085 * Creates a new instance of {@code CallableBackgroundInitializer} and 086 * initializes it with the {@code Callable} to be executed in a background 087 * thread and the {@code ExecutorService} for managing the background 088 * execution. 089 * 090 * @param call the {@code Callable} (must not be <b>null</b>) 091 * @param exec an external {@code ExecutorService} to be used for task 092 * execution 093 * @throws IllegalArgumentException if the {@code Callable} is <b>null</b> 094 */ 095 public CallableBackgroundInitializer(final Callable<T> call, final ExecutorService exec) { 096 super(exec); 097 checkCallable(call); 098 callable = call; 099 } 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}