Executor 框架的一个优点是能运行返回结果的并发任务. Java Concurrent API 提供了以下 2 个接口:
本节的示例代码在 com.elanzone.books.noteeg.chpt4.sect04 package中
FactorialCalculator 类 : 实现 Callable 接口, 参数为 Integer 类型
private Integer number; public FactorialCalculator(Integer number) { this.number = number; }
@Override public Integer call() throws Exception { int result = 1; if ((number == 0) || (number == 1)) { result = 1; } else { for (int i = 2; i <= number; i++) { result *= i; TimeUnit.MILLISECONDS.sleep(20); } } System.out.printf("%s: %d\n", Thread.currentThread().getName(), result); return result; }
控制类 : Main
ThreadPoolExecutor executor = (ThreadPoolExecutor) Executors.newFixedThreadPool(2);
List<Future<Integer>> resultList = new ArrayList<>();
Random random = new Random(); for (int i = 0; i < 10; i++) { Integer number = random.nextInt(10); FactorialCalculator calculator = new FactorialCalculator(number); Future<Integer> result = executor.submit(calculator); resultList.add(result); }
do { System.out.printf("Main: Number of Completed Tasks: %d\n", executor.getCompletedTaskCount()); for (int i = 0; i < resultList.size(); i++) { Future<Integer> result = resultList.get(i); System.out.printf("Main: Task %d: %s\n", i, result.isDone()); } try { TimeUnit.MILLISECONDS.sleep(50); } catch (InterruptedException e) { e.printStackTrace(); } } while (executor.getCompletedTaskCount() < resultList.size());
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("Main: Task %d: %d\n", i, number); }
executor.shutdown();
本例演示了如何使用 Callable 接口启动返回结果的并发任务。 FactorialCalculator 类实现了由 Integer 作为结果类型的 Callable 接口。因此它的 call() 方法返回 Future<Integer> 类型。
另一个重点在 Main 类中。使用 submit() 方法将一个 Callable 对象送去一个执行者内执行。 此方法接受一个 Callable 对象作为参数并返回一个 Future 对象,您可以将 Future 对象用于2个主要目的: