CompletableFuture异步编程


 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 }
View Code


  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 }
View Code
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]));
    }
}
View Code
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;
    }

}
View Code
 
原文地址:https://www.cnblogs.com/sunny-miss/p/13057646.html