多应用+插件架构,代码干净,二开方便,首家独创一键云编译技术,文档视频完善,免费商用码云13.8K 广告
# Java `Future`教程 原文:http://zetcode.com/java/future/ Java `Future`教程展示了如何使用`Future`在 Java 中进行异步编程。 `Future`表示异步计算的结果。 提供了一些方法来检查计算是否完成,等待其完成以及检索计算结果。 简而言之,一旦某个操作完成,就有望保留该操作的结果。 `Future`是 Java 5 中引入的。 该值是使用`get()`从将来检索的,该值将阻塞直到值准备就绪。 `FutureTask`类是实现`Runnable`的`Future`的实现,因此可以由`Executor`执行。 `Future`有几个缺点。 例如,它们无法手动完成,并且它们不会在完成时通知。 `Future`不能被链接和组合。 另外,没有异常处理。 为了解决此缺点,Java8 引入了`CompletableFuture`。 ## Java `Future`示例 以下示例使用`Future`来计算阶乘。 `com/zetcode/FactorialCalculator.java` ```java package com.zetcode; import java.math.BigInteger; import java.util.concurrent.Callable; import java.util.concurrent.TimeUnit; public class FactorialCalculator implements Callable<BigInteger> { private int value; public FactorialCalculator(int value) { this.value = value; } @Override public BigInteger call() throws Exception { var result = BigInteger.valueOf(1); if (value == 0 || value == 1) { result = BigInteger.valueOf(1); } else { for (int i = 2; i <= value; i++) { result = result.multiply(BigInteger.valueOf(i)); } } TimeUnit.MILLISECONDS.sleep(500); return result; } } ``` `FactorialCalculator`使用`BigInteger`计算阶乘。 ```java public class FactorialCalculator implements Callable<BigInteger> { ``` `FactorialCalculator`实现了`Callable`。 `Callable`代表返回结果的异步任务。 在我们的例子中,结果是计算的阶乘。 ```java TimeUnit.MILLISECONDS.sleep(1500); ``` 我们稍微减慢了计算速度。 `com/zetcode/JavaFutureEx.java` ```java package com.zetcode; import java.math.BigInteger; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Random; import java.util.concurrent.ExecutionException; import java.util.concurrent.Executors; import java.util.concurrent.Future; import java.util.concurrent.ThreadPoolExecutor; public class JavaFutureEx { public static void main(String[] args) throws ExecutionException, InterruptedException { var executor = (ThreadPoolExecutor) Executors.newFixedThreadPool(2); List<Map<Integer, Future<BigInteger>>> resultList = new ArrayList<>(); var random = new Random(); for (int i = 0; i < 6; i++) { int number = random.nextInt(100) + 10; var factorialCalculator = new FactorialCalculator(number); Map<Integer, Future<BigInteger>> result = new HashMap<>(); result.put(number, executor.submit(factorialCalculator)); resultList.add(result); } for (Map<Integer, Future<BigInteger>> pair : resultList) { var optional = pair.keySet().stream().findFirst(); if (!optional.isPresent()) { return; } var key = optional.get(); System.out.printf("Value is: %d%n", key); var future = pair.get(key); var result = future.get(); var isDone = future.isDone(); System.out.printf("Result is %d%n", result); System.out.printf("Task done: %b%n", isDone); System.out.println("--------------------"); } executor.shutdown(); } } ``` 我们生成六个随机整数并计算它们的阶乘。 ```java var executor = (ThreadPoolExecutor) Executors.newFixedThreadPool(2); ``` 执行程序服务处理异步任务的生命周期。 它的`submit()`可以接受`Runnable`和`Callable`对象。 ```java var factorialCalculator = new FactorialCalculator(number); ``` 创建一个`FactorialCalculator`任务。 它将异步运行。 ```java Map<Integer, Future<BigInteger>> result = new HashMap<>(); result.put(number, executor.submit(factorialCalculator)); resultList.add(result); ``` 我们将任务提交给执行者。 我们将整数值和`Future`放置在映射上,以便手边有值和计算出的阶乘。 ```java for (Map<Integer, Future<BigInteger>> pair : resultList) { ``` 我们浏览结果列表。 请注意,`Future`在计算其值之前会迅速返回。 ```java var optional = pair.keySet().stream().findFirst(); if (!optional.isPresent()) { return; } var key = optional.get(); ``` 我们得到了一对的钥匙。 ```java var future = pair.get(key); var result = future.get(); ``` 使用钥匙,我们将拥有未来。 当我们调用`get()`时,处理被阻塞,直到检索到该值为止。 ```java Value is: 39 Result is 20397882081197443358640281739902897356800000000 Task done: true -------------------- Value is: 99 Result is 933262154439441526816992388562667004907159682643816214685929638952175999932299156089414639761565182862536979208272237582511852109168640000000000000000000000 Task done: true -------------------- Value is: 39 Result is 20397882081197443358640281739902897356800000000 Task done: true -------------------- Value is: 102 Result is 961446671503512660926865558697259548455355905059659464369444714048531715130254590603314961882364451384985595980362059157503710042865532928000000000000000000000000 Task done: true -------------------- Value is: 12 Result is 479001600 Task done: true -------------------- Value is: 49 Result is 608281864034267560872252163321295376887552831379210240000000000 Task done: true -------------------- ``` 这是一个示例输出。 在本教程中,我们使用了 Java 的`Future`。 列出[所有 Java 教程](/all/#java)。