![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 package com.gupaoedu.completablefuture; 2 3 //折扣类型,包含枚举类型 和应用报价的方法。 4 public class Discount { 5 static double rete = 0.5; 6 7 /** 8 * 模拟查询汇率 9 * @return 10 */ 11 public static double getRate() { 12 return rete; 13 } 14 15 public enum Code{ 16 NONE(0), 17 SILVER(5), 18 GOLD(10), 19 PLATINUM(15), 20 DIAMOND(20); 21 22 private final int percentage; 23 Code(int percentage){ 24 this.percentage = percentage; 25 } 26 } 27 28 public static String applyDiscount(Quote quote){ 29 return quote.getShopName() + " price is " + Discount.apply(quote.getPrice(),quote.getCode()); 30 } 31 32 33 public static double apply(double price, Code code){ 34 delay(); 35 return price * (100 - code.percentage) /100 ; 36 } 37 38 public static void delay(){ 39 try { 40 Thread.sleep(1000L); 41 } catch (InterruptedException e) { 42 e.printStackTrace(); 43 } 44 } 45 }
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 1 package com.gupaoedu.completablefuture; 2 2 3 3 import org.junit.Test; 4 4 import java.util.Arrays; 5 5 import java.util.List; 6 6 import java.util.concurrent.*; 7 7 import static java.util.stream.Collectors.toList; 8 8 9 9 public class Client { 10 10 11 11 @Test 12 12 public void test0() throws Exception { 13 13 long start = System.currentTimeMillis(); 14 14 ExecutorService executorService = Executors.newCachedThreadPool(); 15 15 Future<Double> future = executorService.submit(() -> { 16 16 Thread.sleep(1000L); 17 17 return Math.random(); 18 18 }); 19 19 Thread.sleep(1000L); 20 20 try { 21 21 /** 获取线程执行的结果,传递的是等待线程的时间,单位是1秒 */ 22 22 future.get(1, TimeUnit.SECONDS); 23 23 } catch (ExecutionException e) { 24 24 e.printStackTrace(); 25 25 } catch (TimeoutException e) { 26 26 e.printStackTrace(); 27 27 } 28 28 System.out.println("共耗时" + (System.currentTimeMillis() - start) + "ms");// 1014ms 29 29 } 30 30 31 31 @Test 32 32 public void main() { 33 33 Shop shop = new Shop("BestShop"); 34 34 long start = System.currentTimeMillis(); 35 35 Future<Double> future = shop.getPriceAsync("My Favorite"); 36 36 long invocationTime = System.currentTimeMillis() - start; 37 37 System.out.println("调用接口时间:" + invocationTime + "毫秒"); 38 38 39 39 doSomethingElse(); 40 40 41 41 try { 42 42 double price = future.get(); 43 43 } catch (InterruptedException e) { 44 44 e.printStackTrace(); 45 45 } catch (ExecutionException e) { 46 46 e.printStackTrace(); 47 47 } 48 48 49 49 long retrievalTime = System.currentTimeMillis() - start; 50 50 System.out.println("返回价格消耗时间:" + retrievalTime + "毫秒"); 51 51 52 52 } 53 53 54 54 public static void doSomethingElse() { 55 55 System.out.println("做其他的事情。。。"); 56 56 } 57 57 58 58 @Test 59 59 public void test1() { 60 60 long start = System.currentTimeMillis(); 61 61 System.out.println(findPrice("java8实战")); 62 62 long duration = System.currentTimeMillis() - start; 63 63 System.out.println("总消耗时间:" + duration + "毫秒"); 64 64 } 65 65 66 66 67 67 public static List<String> findPrice(String product) { 68 68 List<Shop> shops = Arrays.asList(new Shop("sunjin.org"), 69 69 new Shop("加瓦匠"), 70 70 new Shop("京东商城"), 71 71 new Shop("天猫商城")); 72 72 return shops.parallelStream() 73 73 .map(shop -> String.format("%s 的价格是 %.2f", shop.getName(), shop.getPrice(product))) 74 74 .collect(toList()); 75 75 } 76 76 77 77 @Test 78 78 public void test2() { 79 79 long start = System.currentTimeMillis(); 80 80 System.out.println(findPrice2("java8实战")); 81 81 long duration = System.currentTimeMillis() - start; 82 82 System.out.println("总消耗时间:" + duration + "毫秒"); 83 83 } 84 84 public static List<String> findPrice2(String product){ 85 85 List<Shop> shops = Arrays.asList(new Shop("sunjin.org"), 86 86 new Shop("加瓦匠"), 87 87 new Shop("京东商城"), 88 88 new Shop("天猫商城")); 89 89 List<CompletableFuture<String>> priceFuture = shops.stream() 90 90 .map(shop -> CompletableFuture.supplyAsync( // 使用异步的方式计算每种商品的价格 91 91 () -> shop.getName() + " 的价格是 " + shop.getPrice(product))) 92 92 .collect(toList()); 93 93 return priceFuture.stream() 94 94 .map(CompletableFuture::join) //join 操作等待所有异步操作的结果 95 95 .collect(toList()); 96 96 } 97 97 98 98 @Test 99 99 public void test3() { 100 100 long start = System.currentTimeMillis(); 101 101 System.out.println(findPrice3("java8实战")); 102 102 long duration = System.currentTimeMillis() - start; 103 103 System.out.println("总消耗时间:" + duration + "毫秒"); 104 104 } 105 105 106 106 public static List<String> findPrice3(String product){ 107 107 List<Shop> shops = Arrays.asList(new Shop("sunjin.org"), 108 108 new Shop("加瓦匠"), 109 109 new Shop("京东商城"), 110 110 new Shop("天猫商城")); 111 111 return shops.stream() 112 112 .map(shop -> shop.getPrice2(product)) //获取原始报价 113 113 .map(Quote::parse) //解析报价字符串 114 114 .map(Discount::applyDiscount) //调用折扣服务应用报价折扣 115 115 .collect(toList()); 116 116 } 117 117 118 118 @Test 119 119 public void test4() { 120 120 long start = System.currentTimeMillis(); 121 121 System.out.println(findPrice4("java8实战")); 122 122 long duration = System.currentTimeMillis() - start; 123 123 System.out.println("总消耗时间:" + duration + "毫秒"); 124 124 } 125 125 126 126 private static Executor executor = Executors.newCachedThreadPool(); 127 127 public static List<String> findPrice4(String product){ 128 128 List<Shop> shops = Arrays.asList(new Shop("sunjin.org"), 129 129 new Shop("加瓦匠"), 130 130 new Shop("京东商城"), 131 131 new Shop("天猫商城")); 132 132 List<CompletableFuture<String>> priceFuture = shops.stream() 133 133 .map(shop -> CompletableFuture.supplyAsync( // 异步获取价格 134 134 () -> shop.getPrice2(product), executor)) 135 135 .map(future -> future.thenApply(Quote::parse)) // 获取到价格后对价格解析 136 136 .map(future -> future.thenCompose(quote -> CompletableFuture.supplyAsync( // 另一个异步任务构造异步应用报价 137 137 () -> Discount.applyDiscount(quote), executor))) 138 138 .collect(toList()); 139 139 return priceFuture.stream() 140 140 .map(CompletableFuture::join) //join 操作和get操作有相同的含义,等待所有异步操作的结果。 141 141 .collect(toList()); 142 142 } 143 143 144 144 145 145 @Test 146 146 public void test5() { 147 147 long start = System.currentTimeMillis(); 148 148 System.out.println(findPrice5("java8实战")); 149 149 long duration = System.currentTimeMillis() - start; 150 150 System.out.println("总消耗时间:" + duration + "毫秒"); 151 151 } 152 152 153 153 public static List<Double> findPrice5(String product){ 154 154 List<Shop> shops = Arrays.asList(new Shop("sunjin.org"), 155 155 new Shop("加瓦匠"), 156 156 new Shop("京东商城"), 157 157 new Shop("天猫商城")); 158 158 List<CompletableFuture<Double>> priceFuture = shops.parallelStream() 159 159 .map(shop -> CompletableFuture.supplyAsync( // 异步获取价格 160 160 () -> shop.getPrice(product), executor)) 161 161 .map(future -> future.thenCombine(CompletableFuture.supplyAsync( // 异步获取折扣率 162 162 () -> Discount.getRate(), executor) 163 163 , (price, rate) -> price * rate)) // 将两个异步任务的结果合并 164 164 .collect(toList()); 165 165 return priceFuture.parallelStream() 166 166 .map(CompletableFuture::join) //join 操作和get操作有相同的含义,等待所有异步操作的结果。 167 167 .collect(toList()); 168 168 } 169 169 170 170 }
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
package com.gupaoedu.completablefuture; public class Quote { private final String shopName; private final double price; private final Discount.Code code; public Quote(String shopName, double price, Discount.Code code) { this.shopName = shopName; this.price = price; this.code = code; } public String getShopName() { return shopName; } public double getPrice() { return price; } public Discount.Code getCode() { return code; } public static Quote parse(String s){ String[] arr = s.split(":"); return new Quote(arr[0], Double.valueOf(arr[1]), Discount.Code.valueOf(arr[2])); } }
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
package com.gupaoedu.completablefuture; import java.util.Random; import java.util.concurrent.CompletableFuture; import java.util.concurrent.Future; public class Shop { private String name; private Random random = new Random(); public Shop(String name) { this.name = name; } //直接获取价格 public double getPrice(String product){ return calculatePrice(product); } //模拟延迟 public static void delay(){ try { Thread.sleep(1000L); } catch (InterruptedException e) { e.printStackTrace(); } } //模拟获取价格的服务 private double calculatePrice(String product){ delay(); return random.nextDouble() * product.charAt(0) + product.charAt(1); } //异步获取价格 public Future<Double> getPriceAsync(String product){ CompletableFuture<Double> future = new CompletableFuture<>(); new Thread(() -> { double price = calculatePrice(product); future.complete(price); }).start(); return future; } public String getName() { return name; } // 获取价格字符串 public String getPrice2(String product){ double price = calculatePrice(product); Discount.Code code = Discount.Code.values()[random.nextInt(Discount.Code.values().length)]; // System.out.println(String.format("s%:%.2f:%s", name, price, code)); System.out.println(name + ":" + price + ":" + code); return name + ":" + price + ":" + code; } }