1、CompletableFuture:
基本的方式创建CompletableFuture<T>对象
package future; import java.util.Optional; import java.util.Random; import java.util.concurrent.CompletableFuture; public class CompletableAction { private static Random random = new Random(); public static void main(String[] args) { CompletableFuture<Double> completableFuture = new CompletableFuture<>(); new Thread(() -> { Double i = get(); completableFuture.complete(i); }).start(); // 使用get方法,会进入阻塞,因此必须等到输出随机数,再输出 123123 /*try { Optional.ofNullable(completableFuture.get()).ifPresent(System.out::println); System.out.println("123123"); } catch (InterruptedException | ExecutionException e) { e.printStackTrace(); }*/ // whenComplete() 方法不会进入阻塞,因此先输出 123123,再输出随机数 completableFuture.whenComplete((v, t) -> { Optional.ofNullable(v).ifPresent(System.out::println); Optional.ofNullable(t).ifPresent(Throwable::printStackTrace); }); System.out.println("123123"); } public static Double get() { try { Thread.sleep(3000L); return (double) random.nextInt(10000); } catch (InterruptedException e) { e.printStackTrace(); return null; } } }
输出的结果:
通过CompletableFuture.supplyAsync(Supplier<T> supplier) 或者 CompletableFuture.supplyAsync(Supplier<T> supplier, Executor executor) 方法进行创建CompletableFuture对象实例
package future; import java.util.Optional; import java.util.concurrent.CompletableFuture; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.atomic.AtomicBoolean; public class CompletableAction2 { public static void main(String[] args) { AtomicBoolean atomicBoolean = new AtomicBoolean(false); ExecutorService executorService = Executors.newFixedThreadPool(2); ExecutorService executorService2 = Executors.newFixedThreadPool(2, (runnable) -> { Thread thread = new Thread(runnable); return thread; }); // supplyAsync(Supplier<T> supplier, Executor executor) 方法, // 采用了 executorService.shutdown()方法 和 AtomicBoolean原子操作判断是否执行完,然后退出线程 CompletableFuture.supplyAsync(CompletableAction::get, executorService2) .whenComplete((v, t) -> { Optional.ofNullable(v).ifPresent(System.out::println); Optional.ofNullable(t).ifPresent(Throwable::printStackTrace); atomicBoolean.set(true); }); System.out.println(123123); while (!atomicBoolean.get()) { try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } } executorService2.shutdown(); //================================================================ // supplyAsync() 方法是一个守护线程, // 当main线程执行完,直接关闭线程,因此supplyAsync()方法的内容来不及打印输出 /*CompletableFuture.supplyAsync(CompletableAction::get) .whenComplete((v, t) -> { Optional.ofNullable(v).ifPresent(System.out::println); Optional.ofNullable(t).ifPresent(Throwable::printStackTrace); }); System.out.println(123123);*/ // 让main线程运行停在这里,没与关闭 /*try { Thread.currentThread().join(); } catch (InterruptedException e) { e.printStackTrace(); }*/ } }
CompletableFuture<T>的 thenApply() 方法和 join() 方法使用
package future; import java.util.Arrays; import java.util.List; import java.util.Optional; import java.util.concurrent.CompletableFuture; import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.atomic.AtomicBoolean; import java.util.stream.Stream; import static java.util.stream.Collectors.toList; public class CompletableAction3 { public static void main(String[] args) { List<Integer> integers = Arrays.asList(1, 2, 3, 4, 5); AtomicBoolean atomicBoolean = new AtomicBoolean(false); ExecutorService executorService = Executors.newFixedThreadPool(2, (r) -> { Thread thread = new Thread(r); return thread; }); /*CompletableFuture.supplyAsync(CompletableAction::get, executorService).whenComplete((v, t) -> { atomicBoolean.set(true); Optional.ofNullable(v).ifPresent(System.out::println); Optional.ofNullable(t).ifPresent(Throwable::printStackTrace); }); while (!atomicBoolean.get()) { executorService.shutdown(); }*/ // 原始方式使用 Stream<CompletableFuture<Double>> completableFutureStream = integers.stream().map(i -> { return CompletableFuture.supplyAsync(() -> CompletableAction3.getProductById(i), executorService); }); Stream<Double> doubleStream = completableFutureStream.map(d -> { Double multiply = null; try { multiply = CompletableAction3.multiply(d.get()); } catch (InterruptedException | ExecutionException e) { e.printStackTrace(); } return multiply; }); List<Double> doubleList = doubleStream.collect(toList()); Optional.of(doubleList).ifPresent(System.out::println); // CompletableFuture的 join() 和 thenApply() 方法使用 Stream<CompletableFuture<Double>> completableFutureStream2 = integers.stream().map(i -> { return CompletableFuture.supplyAsync(() -> CompletableAction3.getProductById(i), executorService); }); Stream<CompletableFuture<Double>> completableFutureStream1 = completableFutureStream.map(future -> { return future.thenApply(CompletableAction3::multiply); }); Stream<Double> doubleStream2 = completableFutureStream1.map(CompletableFuture::join); List<Double> doubleList2 = doubleStream.collect(toList()); Optional.of(doubleList2).ifPresent(System.out::println); } // 模拟取到数据之后进行相关业务操作,这里模拟取到的数据 * 10 public static Double multiply(Double d) { try { Thread.sleep(3000); return d * 10d; } catch (InterruptedException e) { e.printStackTrace(); return null; } } // 模拟根据 ID 查询商品 public static Double getProductById(int i) { Double aDouble = CompletableAction.get(); System.out.println(aDouble); return aDouble; } }
常用api:
package future; import java.util.Arrays; import java.util.List; import java.util.concurrent.CompletableFuture; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.stream.Stream; import static java.util.stream.Collectors.toList; public class CompletableAction4 { public static void main(String[] args) throws InterruptedException { ExecutorService executorService = Executors.newFixedThreadPool(2, (r) -> { Thread thread = new Thread(r); return thread; }); // thenApply()、supplyAsync()、whenComplete() 方法 CompletableFuture.supplyAsync(() -> 1d) .thenApply(CompletableAction3::multiply) .whenComplete((v, t) -> { System.out.println(v); }); // thenRun() 方法 CompletableFuture.supplyAsync(() -> 1) .thenRun(() -> { System.out.println("========》 use the thenRun() method"); }); // thenAccept() 方法 CompletableFuture.supplyAsync(() -> 1) .thenAccept(r -> { System.out.println("========》 use the thenAccept() method: " + r); }); // thenCompose() 方法 CompletableFuture.supplyAsync(() -> 1) .thenApply(r -> r * 10d) .thenCompose(r -> CompletableFuture.supplyAsync(() -> r)) .thenAccept(r -> { System.out.println("========》 use the thenCompose() method: " + r); }); // thenCombine() 方法, 有返回值 CompletableFuture.supplyAsync(() -> 1) .thenCombine(CompletableFuture.supplyAsync(() -> 2d), (r1, r2) -> { System.out.println("========》 use the thenCombine() method: " + (r1 + r2)); return r1 + r2; }); // thenAcceptBoth() 方法,无返回值。和 then Combine() 方法类似, CompletableFuture.supplyAsync(()-> 1) .thenAcceptBoth(CompletableFuture.supplyAsync(() -> 3d), (r1, r2) -> { System.out.println("========》 use the thenAcceptBoth() method: " + (r1 + r2)); }); // runAfterBoth() 方法,直接执行完。只有两个 CompletableFuture 对象实例化完成才返回 CompletableFuture.supplyAsync(() -> { // try { // Thread.sleep(2000); // System.out.println("sleep 2s"); // } catch (InterruptedException e) { // e.printStackTrace(); // } return 1; }).runAfterBoth(CompletableFuture.supplyAsync(() -> { // try { // Thread.sleep(3000); // System.out.println("sleep 3s"); // } catch (InterruptedException e) { // e.printStackTrace(); // } return 2; }), () -> System.out.println("========》 use the runAfterBoth() method")); // runAfterEither() 方法,直接执行完。只要有一个 CompletableFuture 对象实例化完成就直接返回 CompletableFuture.supplyAsync(() -> { // try { // Thread.sleep(2000); // System.out.println("sleep 2s"); // } catch (InterruptedException e) { // e.printStackTrace(); // } return 1; }).runAfterEither(CompletableFuture.supplyAsync(() -> { // try { // Thread.sleep(3000); // System.out.println("sleep 3s"); // } catch (InterruptedException e) { // e.printStackTrace(); // } return 2; }), () -> System.out.println("========》 use the runAfterEither() method")); // acceptEither() 方法 CompletableFuture.supplyAsync(() -> 1) .acceptEither(CompletableFuture.supplyAsync(() -> 2), (r1) -> { System.out.println("========》 use the acceptEither() method:" + r1); }); // acceptEither() 方法 CompletableFuture.supplyAsync(() -> 1) .applyToEither(CompletableFuture.supplyAsync(() -> 2), (r1) -> r1 * 10d) .whenComplete((v, t) -> { System.out.println("========》 use the applyToEither() method:" + v); }); // allOf() 方法 必须等所有的实例化完,才返回。前提条件是线程没结束 List<Integer> integers = Arrays.asList(1, 2, 3, 4, 5); Stream<CompletableFuture<Integer>> completableFutureStream = integers.stream().map(i -> CompletableFuture.supplyAsync(() -> { System.out.println(i); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } return i; })); List<CompletableFuture<Integer>> completableFutureList = completableFutureStream.collect(toList()); CompletableFuture[] completableFutures = completableFutureList.toArray(new CompletableFuture[completableFutureList.size()]); CompletableFuture.allOf(completableFutures) .thenApply(r -> 10d) .whenComplete((v, t) -> { System.out.println("========》 use the allOf() method:" + v); t.printStackTrace(); }); // anyOf() 方法, 只要有一个实例化完直接返回,前提条件是线程没结束 List<Integer> integers2 = Arrays.asList(1, 2, 3, 4, 5); Stream<CompletableFuture<Integer>> completableFutureStream2 = integers2.stream().map(i -> CompletableFuture.supplyAsync(() -> { System.out.println(i); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } return i; })); List<CompletableFuture<Integer>> completableFutureList2 = completableFutureStream2.collect(toList()); CompletableFuture[] completableFutures2 = completableFutureList.toArray(new CompletableFuture[completableFutureList2.size()]); CompletableFuture.anyOf(completableFutures2) .thenApply(r -> 10d) .whenComplete((v, t) -> { System.out.println("========》 use the anyOf() method:" + v); }); Thread.currentThread().join(); } }
来源:oschina
链接:https://my.oschina.net/u/3901188/blog/3189204