认识和使用CompletableFuture
CompletableFuture是ExecutorService的改进版
首先来了解ExecutorService怎么使用
void executorServiceTest() throws InterruptedException, ExecutionException { ExecutorService executorService = Executors.newSingleThreadExecutor(); Future<String> future = executorService.submit(() -> { try { Thread.sleep(10000L); return "I am finished."; } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); return "I am Error"; } }); while(!future.isDone()) { Thread.sleep(10); } System.out.println(future.get()); executorService.shutdown(); }
CompletableFuture对ExecutorService做了简化和改进
使用方式:
private final static Random RANDOM = new Random(System.currentTimeMillis()); public static void main(String[] args) throws Exception { CompletableFuture<Double> completableFuture = new CompletableFuture<>(); new Thread(() -> { double value = get(); completableFuture.complete(value); }).start(); System.out.println("no === block..."); completableFuture.whenComplete((v,t) -> { System.out.println(v);; }); } private static double get() { try { Thread.sleep(RANDOM.nextInt(10000)); }catch(Exception e) { e.printStackTrace(); } return RANDOM.nextDouble(); }
场景1:连续算5个商品的价格
public class CompletableFutureAPITest { public static void main(String[] args) { ExecutorService executorService = Executors.newFixedThreadPool(2, r ->{ Thread t = new Thread(r); t.setDaemon(false); return t; }); List<Integer> productIds = Arrays.asList(1,2,3,4,5); Stream<CompletableFuture<Double>> completableFutureStream = productIds.stream().map(i -> CompletableFuture.supplyAsync(() -> get(i),executorService)); Stream<CompletableFuture<Double>> multiplyFutures = completableFutureStream.map(future -> future.thenApply(CompletableFutureAPITest::mutiply)); List<Double> result = multiplyFutures.map(CompletableFuture::join).collect(Collectors.toList()); System.out.println(result); } public static double mutiply(double value) { try { Thread.sleep(1000); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } System.out.println(value * 10d); return value * 10d; } public static double get(int i) { try { Thread.sleep(1000); }catch(Exception e) { e.printStackTrace(); } return i; } }
控制台输出: