场景就是,异步查询各家商店的书价格,然后返回。
第一步:首先定义一个shop类商店。
import java.util.Random;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.Future;
public class Shop {
String name;
public double getPrice(){
return calcPrice(); //模拟返回一个价格
}
private double calcPrice(){
delay();
Random random = new Random();
return random.nextDouble();
}
public static void delay(){
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public Future<Double> getPriceAsyn(String product){
CompletableFuture<Double> futurePrice = new CompletableFuture<>();
new Thread(()->{
double price = calcPrice();
futurePrice.complete(price);
}).start();
return futurePrice;
}
}
第二步,测试类:
public static void doSomeThingElse(){
System.out.println("此处去查询其他的数据,例如其他shop的价格,同时在异步获取javaBook的价格");
}
public static void main(String[] args) {
Shop shop = new Shop();
long start = System.nanoTime();
Future<Double> futurePrice = shop.getPriceAsyn("javaBook");
doSomeThingElse();
try {
double price = futurePrice.get();
System.out.println("最后Book的价格是: "+price);
} catch (InterruptedException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
long realTime =((System.nanoTime())-start)/1_000_000;
System.out.println("price return after: "+realTime+"msecs");
}
}
输出结果:
此处去查询其他的数据,例如其他shop的价格,同时在异步获取javaBook的价格
最后Book的价格是: 0.6837328987952977
price return after: 3159msecs
============================================ 万能的分割线===================================================
以上是CompletableFuture 类的基本使用,实际中可以更进一步,使用工厂方法创建CompletableFuture 对象
CompletableFuture 类自身提供了大量的工厂方法,使用这些方法能更加容易地完成整个流程,不用关注具体实现的细节。
例如采用 supplyAsync 方法
public class Shop2 {
String name;
public double getPrice(){
return calcPrice(); //模拟返回一个价格
}
private double calcPrice(){
delay();
Random random = new Random();
return random.nextDouble();
}
public static void delay(){
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public Future<Double> getPriceAsyn(String product){
// CompletableFuture<Double> futurePrice = new CompletableFuture<>();
// new Thread(()->{
// double price = calcPrice();
// futurePrice.complete(price);
// }).start();
// return futurePrice;
return CompletableFuture.supplyAsync(()->calcPrice());//此处用一行代码替代上面一段代码
}
}
测试类:
public class Future_test03 {
public static void doSomeThingElse(){
System.out.println("此处去查询其他的数据,例如其他shop的价格,同时在异步获取javaBook的价格");
}
public static void main(String[] args) {
Shop2 shop = new Shop2();//就这里不一样
long start = System.nanoTime();
Future<Double> futurePrice = shop.getPriceAsyn("javaBook");
doSomeThingElse();
try {
double price = futurePrice.get();
System.out.println("最后Book的价格是: "+price);
} catch (InterruptedException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
long realTime =((System.nanoTime())-start)/1_000_000;
System.out.println("price return after: "+realTime+" msecs");
}
}
执行结果如下:
此处去查询其他的数据,例如其他shop的价格,同时在异步获取javaBook的价格
最后Book的价格是: 0.22343324105430296
price return after: 3204 msecs
效果明显是一样的。
supplyAsync 方法接受一个生产者(Supplier)作为参数,返回一个CompletableFuture对象,该对象完成异步执行后会读取调用生产者方法的返回值。生产者交给ForkJoinPool池中的某个执行线程Executor()运行。PS:也可以采用supplyAsync 的重载版本,传递第二个参数指定不同的执行线程执行生产者方法。