ThreadPoolExecutor提供了另一个非常强有力的接口,那就是callable。这个接口和runnable类似,但是实现这个接口的方法是call方法,这个方法是可以返回值的,弥补了runnable不能返回值的悲哀。而且这个方法可以配合ThreadPoolExecutor使用,获得Future接口,从这个接口的名字我们就能知道,返回的这个类似于指向这个线程的一个指针,我们能通过这个Future接口知道当前线程的运行情况,包括是否已经完成任务,目前运行情况,运行完成后的返回值等,而且每个任务创建后直接通过ThreadPoolExecutor的submit方法提供,有一种非常自动化的感觉。爱不释手,简直停不下来。下面我们就以计算多个数字的阶层为例子演示一下这个接口的使用方法。
一、Response
public class Response<T> implements Serializable {
private String key;
private T response;
public Response(String key, T response) {
this.key = key;
this.response = response;
}
public String getKey() {
return key;
}
public T getResponse() {
return response;
}
}
二、Task
public abstract class Task<T> implements Callable<Response<T>> {
private String key;
private Object parameter;
public Task(String key, Object parameter) {
this.key = key;
this.parameter = parameter;
}
public abstract T execute(Object parameter);
@Override
public Response<T> call() throws Exception {
T result = execute(parameter);
Response response = new Response(key, result);
return response;
}
}
三、TaskExecutor
public class TaskExecutor {
private static TaskExecutor instance = new TaskExecutor();
private final int invokerPoolSize = 400;
private final int load_factor = 10;
BlockingQueue<Runnable> queue = new ArrayBlockingQueue<Runnable>(invokerPoolSize * load_factor);
ThreadPoolExecutor executor = new ThreadPoolExecutor(invokerPoolSize, invokerPoolSize, 0L, TimeUnit.MILLISECONDS, queue,
new ThreadPoolExecutor.CallerRunsPolicy());
private TaskExecutor() {
}
public static TaskExecutor getInstance() {
if (instance == null) {
throw new IllegalStateException("TaskExecutor not initiated yet!");
}
return instance;
}
public ThreadPoolExecutor getExecutor() {
return executor;
}
}
四、测试
public class TestCallable {
public static void main(String[] args) throws ExecutionException, InterruptedException {
List<Task<Map<String, String>>> tasksList = buildAsynTasks();
List<Future<Response<Map<String, String>>>> futures = com.google.common.collect.Lists.newArrayList();
for(Task<Map<String, String>> task : tasksList){
Future<Response<Map<String, String>>> future = TaskExecutor.getInstance().getExecutor().submit(
task);
futures.add(future);
}
for (Future fu : futures){
System.out.println(fu.get().getClass());
}
}
public static List<Task<Map<String, String>>> buildAsynTasks() {
List<Task<Map<String, String>>> rankTaskList = Lists.newArrayList();
Task<Map<String, String>> task1 = buildAsynTask("task1", "parameter1");
Task<Map<String, String>> task2 = buildAsynTask("task2", "parameter2");
Task<Map<String, String>> task3 = buildAsynTask("task3", "parameter3");
Task<Map<String, String>> task4 = buildAsynTask("task4", "parameter4");
rankTaskList.add(task1);
rankTaskList.add(task2);
rankTaskList.add(task3);
rankTaskList.add(task4);
return rankTaskList;
}
public static Task<Map<String,String>> buildAsynTask(final String key,final String parameter){
Task<Map<String,String>> task = new Task<Map<String, String>>(key,parameter) {
@Override
public Map<String, String> execute(Object parameters) {
Map<String, String> map = Maps.newHashMap();
map.put(key, parameter);
return map;
}
};
return task;
}
}