4.3运用执行器返回结果
Executor框架的优势之一就是你能够运行并发的任务并且获得对应的结果。Java 并发API完成这个功能是通过下面两个接口:
l Callable: 这个接口有call()方法。在这个方法中,你不得不实现一个任务的逻辑代码。Callable接口是一个参数化的接口,意味着你不得不说明call()方法返回的数据类型。
l Future:这个接口有一些方法去获取由Callable对象产生的结果和管理它的状态。
下面看一个例子,比较好的说明了如何使用Callable和Future类。
import java.util.ArrayList;
import java.util.List;
//import java.util.Random;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.ThreadPoolExecutor;
public class FactorialCalculator implements Callable<Integer> {
/**
* Number to calculate the factorial
*/
private Integer number;
public FactorialCalculator(){
}
/**
* Constructor of the class. Initializes the attributes
* @param number Number to calculate the factorial
*/
public FactorialCalculator(Integer number){
this.number=number;
}
/**
* Method called by the executor to execute this task and calculate the factorial of a
* number
*/
@Override
public Integer call() throws Exception {
int num, result;
num=number.intValue();
result=1;
// If the number is 0 or 1, return the 1 value
if ((num==0)||(num==1)) {
result=1;
} else {
// Else, calculate the factorial
for (int i=2; i<=number; i++) {
result *= i;
Thread.sleep(20);
}
}
System.out.printf("%s: %d\n",Thread.currentThread().getName(),result);
// Return the value
return result;
}
public void invokeCalling(){
// Create a ThreadPoolExecutor with fixed size. It has a maximun of two threads
ThreadPoolExecutor executor=(ThreadPoolExecutor)Executors.newFixedThreadPool(2);
// List to store the Future objects that control the execution of the task and
// are used to obtain the results
List<Future<Integer>> resultList=new ArrayList<Future<Integer>>();
// Create a random number generator
// Random random=new Random();
// Create and send to the executor the ten tasks
for (int i=0; i<10; i++){
Integer number=new Integer(i);
FactorialCalculator calculator=new FactorialCalculator(number);
Future<Integer> result=executor.submit(calculator);
resultList.add(result);
}
// Wait for the finalization of the ten tasks
do {
System.out.printf("Main: Number of Completed Tasks: %d\n"
,executor.getCompletedTaskCount());
int size = resultList.size();
for (int i=0; i<size; i++) {
Future<Integer> result=resultList.get(i);
System.out.printf("Main: Task %d: %s\n", i, result.isDone());
}
try {
Thread.sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
}
} while (executor.getCompletedTaskCount()<resultList.size());
// Write the results
System.out.printf("Main: Results\n");
for (int i=0; i<resultList.size(); i++) {
Future<Integer> result=resultList.get(i);
Integer number=null;
try {
number=result.get();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
System.out.printf("Core: Task %d: %d\n",i,number);
}
// Shutdown the executor
executor.shutdown();
}
public static void main(String []args){
(new FactorialCalculator()).invokeCalling();
}
}
运行结果:
pool-1-thread-1: 1
Main: Number of Completed Tasks: 0
pool-1-thread-2: 1
Main: Task 0: true
Main: Task 1: true
Main: Task 2: false
Main: Task 3: false
Main: Task 4: false
Main: Task 5: false
Main: Task 6: false
Main: Task 7: false
Main: Task 8: false
Main: Task 9: false
pool-1-thread-1: 2
pool-1-thread-2: 6
Main: Number of Completed Tasks: 4
Main: Task 0: true
Main: Task 1: true
Main: Task 2: true
Main: Task 3: true
Main: Task 4: false
Main: Task 5: false
Main: Task 6: false
Main: Task 7: false
Main: Task 8: false
Main: Task 9: false
pool-1-thread-1: 24
Main: Number of Completed Tasks: 5
Main: Task 0: true
Main: Task 1: true
Main: Task 2: true
Main: Task 3: true
Main: Task 4: true
Main: Task 5: false
Main: Task 6: false
Main: Task 7: false
Main: Task 8: false
Main: Task 9: false
pool-1-thread-2: 120
Main: Number of Completed Tasks: 6
Main: Task 0: true
Main: Task 1: true
Main: Task 2: true
Main: Task 3: true
Main: Task 4: true
Main: Task 5: true
Main: Task 6: false
Main: Task 7: false
Main: Task 8: false
Main: Task 9: false
pool-1-thread-1: 720
Main: Number of Completed Tasks: 7
Main: Task 0: true
Main: Task 1: true
Main: Task 2: true
Main: Task 3: true
Main: Task 4: true
Main: Task 5: true
Main: Task 6: true
Main: Task 7: false
Main: Task 8: false
Main: Task 9: false
pool-1-thread-2: 5040
Main: Number of Completed Tasks: 8
Main: Task 0: true
Main: Task 1: true
Main: Task 2: true
Main: Task 3: true
Main: Task 4: true
Main: Task 5: true
Main: Task 6: true
Main: Task 7: true
Main: Task 8: false
Main: Task 9: false
Main: Number of Completed Tasks: 8
Main: Task 0: true
Main: Task 1: true
Main: Task 2: true
Main: Task 3: true
Main: Task 4: true
Main: Task 5: true
Main: Task 6: true
Main: Task 7: true
Main: Task 8: false
Main: Task 9: false
pool-1-thread-1: 40320
Main: Number of Completed Tasks: 9
Main: Task 0: true
Main: Task 1: true
Main: Task 2: true
Main: Task 3: true
Main: Task 4: true
Main: Task 5: true
Main: Task 6: true
Main: Task 7: true
Main: Task 8: true
Main: Task 9: false
pool-1-thread-2: 362880
Main: Results
Core: Task 0: 1
Core: Task 1: 1
Core: Task 2: 2
Core: Task 3: 6
Core: Task 4: 24
Core: Task 5: 120
Core: Task 6: 720
Core: Task 7: 5040
Core: Task 8: 40320
Core: Task 9: 362880