概述
CompletableFuture 是JDK8提供的对于Future接口的扩展,增加了supplyAsync()和join()等方法来扩展Future接口对于函数编程的支持。
实例
核心代码
// 1.使用supplyAsync()方法创建异步线程
public Future<Double> getPriceAsync2(String product) {
return CompletableFuture.supplyAsync(() -> calculatePrice(product));
}
// 2.使用创建好的异步线程,并通过调用get()方法执行相应的计算
Future<Double> futurePrice = shop.getPriceAsync2("my favorite product");
Double price = futurePrice.get();
全部代码
Shop 类
public class Shop {
private static final Random random = new Random();
private String name;
public Shop(String name) {
this.name = name;
}
/**
* 获得价格
*/
public double getPrice(String product) {
// 待实现
return calculatePrice(product);
}
/**
* 获得价格(异步 - 版本1)
*/
public Future<Double> getPriceAsync1(String product) {
CompletableFuture<Double> futurePrice = new CompletableFuture<>();
new Thread(() -> {
try {
double price = calculatePrice(product);
// 正常计算技术,完成这次Future操作
futurePrice.complete(price);
} catch (Exception e) {
// 抛出导致失败的异常,完成这次Future操作
futurePrice.completeExceptionally(e);
}
}).start();
return futurePrice;
}
/**
* 获得价格(异步 - 版本2)
*/
public Future<Double> getPriceAsync2(String product) {
return CompletableFuture.supplyAsync(() -> calculatePrice(product));
}
/**
* 计算价格
*/
private double calculatePrice(String product) {
delay();
// 模拟计算
return random.nextDouble() * product.charAt(0) + product.charAt(1);
}
/**
* 延迟1s
*/
public static void delay() {
try {
Thread.sleep(1000L);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
}
测试类
public class Test {
@Data
@AllArgsConstructor
static
class Aoo {
private String name;
private Integer age;
}
public static void main(String[] args) {
Shop shop = new Shop("BestShop");
long start = System.nanoTime();
Future<Double> futurePrice = shop.getPriceAsync2("my favorite product");
long invocationTime = (System.nanoTime() - start) / 1_000_000;
System.out.println("Invocation returned after " + invocationTime + " msecs");
// 执行更多任务,比如查询其他商店
doSomethingElse();
// 在计算商品价格的同时
try {
Double price = futurePrice.get();
System.out.printf("Price is %.2f%n", price);
invocationTime = (System.nanoTime() - start) / 1_000_000;
System.out.println("Invocation returned after " + invocationTime + " msecs");
} catch (Exception e) {
throw new RuntimeException(e);
}
}
/**
* 访问其他商店
*/
private static void doSomethingElse() {
}
}
输出结果:
Invocation returned after 53 msecs
Price is 134.48
Invocation returned after 1069 msecs
注意:异步编程只是增加系统的吞吐量,并不能增加系统的执行速度!