原文: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
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;}@Overridepublic 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计算阶乘。
public class FactorialCalculator implements Callable<BigInteger> {
FactorialCalculator实现了Callable。 Callable代表返回结果的异步任务。 在我们的例子中,结果是计算的阶乘。
TimeUnit.MILLISECONDS.sleep(1500);
我们稍微减慢了计算速度。
com/zetcode/JavaFutureEx.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();}}
我们生成六个随机整数并计算它们的阶乘。
var executor = (ThreadPoolExecutor) Executors.newFixedThreadPool(2);
执行程序服务处理异步任务的生命周期。 它的submit()可以接受Runnable和Callable对象。
var factorialCalculator = new FactorialCalculator(number);
创建一个FactorialCalculator任务。 它将异步运行。
Map<Integer, Future<BigInteger>> result = new HashMap<>();result.put(number, executor.submit(factorialCalculator));resultList.add(result);
我们将任务提交给执行者。 我们将整数值和Future放置在映射上,以便手边有值和计算出的阶乘。
for (Map<Integer, Future<BigInteger>> pair : resultList) {
我们浏览结果列表。 请注意,Future在计算其值之前会迅速返回。
var optional = pair.keySet().stream().findFirst();if (!optional.isPresent()) {return;}var key = optional.get();
我们得到了一对的钥匙。
var future = pair.get(key);var result = future.get();
使用钥匙,我们将拥有未来。 当我们调用get()时,处理被阻塞,直到检索到该值为止。
Value is: 39Result is 20397882081197443358640281739902897356800000000Task done: true--------------------Value is: 99Result is 933262154439441526816992388562667004907159682643816214685929638952175999932299156089414639761565182862536979208272237582511852109168640000000000000000000000Task done: true--------------------Value is: 39Result is 20397882081197443358640281739902897356800000000Task done: true--------------------Value is: 102Result is 961446671503512660926865558697259548455355905059659464369444714048531715130254590603314961882364451384985595980362059157503710042865532928000000000000000000000000Task done: true--------------------Value is: 12Result is 479001600Task done: true--------------------Value is: 49Result is 608281864034267560872252163321295376887552831379210240000000000Task done: true--------------------
这是一个示例输出。
在本教程中,我们使用了 Java 的Future。 列出所有 Java 教程。
