• CompletableFuture详解1


    初识CompletableFuture

    package com.dwz.executors;
    
    import java.util.List;
    import java.util.concurrent.Callable;
    import java.util.concurrent.CompletableFuture;
    import java.util.concurrent.ExecutorService;
    import java.util.concurrent.Executors;
    import java.util.concurrent.ThreadLocalRandom;
    import java.util.concurrent.TimeUnit;
    import java.util.stream.Collectors;
    import java.util.stream.IntStream;
    
    public class CompletableFutureExample1 {
        
        private static void testCompletableFuture() throws InterruptedException {
            //执行的线程默认是守护线程,会随着主线程的结束而结束
            CompletableFuture.runAsync(() -> {
                try {
                    TimeUnit.SECONDS.sleep(10);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }).whenComplete((v, t) -> System.out.println("DONE."));
            
            System.out.println("=========I am not blocked.========");
            
            Thread.currentThread().join();
        }
        
        private static void display(int data) {
            int value = ThreadLocalRandom.current().nextInt(20);
            
            try {
                System.out.println(Thread.currentThread().getName() + " display will be sleep " + value);
                TimeUnit.SECONDS.sleep(value);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(Thread.currentThread().getName() + " display execute done " + data);
        }
        
        private static int get1() {
            int value = ThreadLocalRandom.current().nextInt(20);
            
            try {
                System.out.println(Thread.currentThread().getName() + " get will be sleep " + value);
                TimeUnit.SECONDS.sleep(value);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(Thread.currentThread().getName() + " get execute done " + value);
            return value;
        }
        
        //前后执行的get1()和display()有先后执行顺序,必须等待get1()全部执行完
        private static void testOld() throws InterruptedException {
            ExecutorService executorService = Executors.newFixedThreadPool(10);
            List<Callable<Integer>> tasks = IntStream.range(0, 10).boxed().map(i -> (Callable<Integer>)() -> get1()).collect(Collectors.toList());
            executorService.invokeAll(tasks).stream().mapToInt(future -> {
                try {
                    //阻塞
                    return future.get();
                } catch (Exception e) {
                    throw new RuntimeException(e);
                }
            }).parallel().forEach(CompletableFutureExample1::display);
        }
        
        //前后执行的get1()和display()完全并行,get1()执行完成之后就可以接着执行display()
        private static void testNew() throws InterruptedException {
            IntStream.range(0, 10).boxed()
            .forEach(i -> CompletableFuture.supplyAsync(CompletableFutureExample1::get1)
                    .thenAccept(CompletableFutureExample1::display)
                    .whenComplete((v, t) -> System.out.println(i + "DONE.")));
    
            Thread.currentThread().join();
        }
        
    }

    CompletableFuture方法大纲

    CompletableFuture的方法总结:
    1.factory method
    *supplyAsync
    *runAsync
    *completedFuture
    *anyOf
    *allOf
    2.intermate
    2.1 return T
    *whenComplete biconsumer
    *whenCompleteAsync
    *thenApply
    *thenApplyAsync
    *handleAsync biFunction
    *handle
    2.2 return void
    *thenAcceptAsync
    *thenAccept
    *thenRunAsync
    *thenRun
    3.compose
    * ThenAcceptBoth
    * AcceptEither
    * RunAfterBothAsync
    * RunAfterEither
    * Combine
    * Compose
    4.terminated
    * getNow
    * complete
    * join
    * completeExceptionally
    * obtrudeException
    * exceptionally

    factory method 工厂方法

    package com.dwz.executors;
    
    import java.util.concurrent.CompletableFuture;
    import java.util.concurrent.ExecutionException;
    import java.util.concurrent.Future;
    import java.util.concurrent.TimeUnit;
    
    public class CompletableFutureExample2 {
        /*
         *     情景:
         *     在表里面插入基本信息和详细信息,最后再执行某些操作,插入的动作没有先后顺序
         *                 insert basic    
         *     【submit】                     ===>do action
         *                 insert details
         */
        private static void supplyAsync() {
            CompletableFuture.supplyAsync(Object::new).thenAcceptAsync(obj -> {
                try {
                    System.out.println("Object===========Start");
                    TimeUnit.SECONDS.sleep(5);
                    System.out.println("Object===========" + obj);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }).runAfterBoth(CompletableFuture.supplyAsync(() -> "Hello").thenAcceptAsync(s -> {
                try {
                    System.out.println("String===========Start");
                    TimeUnit.SECONDS.sleep(3);
                    System.out.println("String===========" + s);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }), () -> System.out.println("=========Finished========"));
        }
        
        private static Future<?> runAsync() {
            return CompletableFuture.runAsync(() -> {
                try {
                    System.out.println("Object===========Start");
                    TimeUnit.SECONDS.sleep(5);
                    System.out.println("Object===========End");
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }).whenComplete((v, t) -> System.out.println("==========over========="));
        }
        
        private static Future<Void> completed(String data) {
            return CompletableFuture.completedFuture(data).thenAccept(System.out::println);
        }
        
        /*
         *     只返回级联中的一个行为值,其他行为也会异步正常执行结束
         */
        private static Future<?> anyOf() {
            return CompletableFuture.anyOf(CompletableFuture.runAsync(() -> {
                try {
                    System.out.println("1===========Start");
                    TimeUnit.SECONDS.sleep(5);
                    System.out.println("1===========End");
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }).whenComplete((v, t) -> System.out.println("==========over=========")),
            CompletableFuture.supplyAsync(() -> {
                try {
                    System.out.println("2===========Start");
                    TimeUnit.SECONDS.sleep(4);
                    System.out.println("2===========End");
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                return "Hello";
            }).whenComplete((v, t) -> System.out.println(v + "==========over=========")));
        }
        
        /*
         *     所有行为异步正常执行结束,没有返回值
         */
        private static void allOf() {
            CompletableFuture.allOf(CompletableFuture.runAsync(() -> {
                try {
                    System.out.println("1===========Start");
                    TimeUnit.SECONDS.sleep(5);
                    System.out.println("1===========End");
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }).whenComplete((v, t) -> System.out.println("==========over=========")),
            CompletableFuture.supplyAsync(() -> {
                try {
                    System.out.println("2===========Start");
                    TimeUnit.SECONDS.sleep(4);
                    System.out.println("2===========End");
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                return "Hello";
            }).whenComplete((v, t) -> System.out.println(v + "==========over=========")));
        }
        
        private static void create() {
            CompletableFuture<Object> future = new CompletableFuture();
            //等价于
            Object s = null;
            CompletableFuture.<Object>supplyAsync(() -> s);
        }
    }

    测试方法:

    public static void main(String[] args) throws InterruptedException, ExecutionException {
            supplyAsync();
            runAsync();
            completed("dandan");
            System.out.println(">>>>>"+anyOf().get());
            allOf();
            Thread.currentThread().join();
        }

    intermate  return T or  return void 

    package com.dwz.executors;
    
    import java.util.Optional;
    import java.util.concurrent.CompletableFuture;
    import java.util.concurrent.ExecutionException;
    import java.util.concurrent.TimeUnit;
    import java.util.function.Supplier;
    
    public class CompletableFutureExample3 {
        //有返回值的方法
        private static void testWhenComplete() throws InterruptedException, ExecutionException {
            CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> "Hello");
            future.whenComplete((v, t) -> {
                try {
                    System.out.println("==============");
                    TimeUnit.SECONDS.sleep(2);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println("=======over=======");
            });
            System.out.println(future.get());
        }
        
        private static void testWhenCompleteAsync() throws InterruptedException, ExecutionException {
            CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> "Hello");
            future.whenCompleteAsync((v, t) -> {
                try {
                    System.out.println("==============");
                    TimeUnit.SECONDS.sleep(2);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println("=======over=======");
            });
            System.out.println(future.get());
        }
        
        //入参是function
        private static void testThenApply() throws InterruptedException, ExecutionException {
            CompletableFuture<Integer> future = CompletableFuture.supplyAsync(() -> "Hello").thenApply(s -> {
                try {
                    System.out.println("==============");
                    TimeUnit.SECONDS.sleep(2);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println("=======over=======");
                return s.length();
            });
            System.out.println(future.get());
        }
        
        private static void testThenApplyAsync() throws InterruptedException, ExecutionException {
            CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> "Hello");
            CompletableFuture<Integer> future2 = future.thenApplyAsync(s -> {
                try {
                    System.out.println("==============");
                    TimeUnit.SECONDS.sleep(2);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println("=======over=======");
                return s.length();
            });
            System.out.println(future.get());
        }
        
        //对异常进行处理并返回新值
        private static void testHandle() throws InterruptedException, ExecutionException {
            CompletableFuture<Integer> future = CompletableFuture.supplyAsync((Supplier<String>)() -> {
                throw new RuntimeException("not get the data");
            }).handle((s, t) -> {
                Optional.of(t).ifPresent(e -> System.out.println("Error"));
                return (s == null) ? 0 : s.length();
            });
            System.out.println(future.get());
        }
        
        private static void testHandleAsync() throws InterruptedException, ExecutionException {
            CompletableFuture<String> future = CompletableFuture.supplyAsync((Supplier<String>)() -> {
                throw new RuntimeException("not get the data");
            });
            CompletableFuture<Integer> future2 = future.handleAsync((s, t) -> {
                Optional.of(t).ifPresent(e -> System.out.println("Error"));
                return (s == null) ? 0 : s.length();
            });
            System.out.println(future2.get());
        }
        
        //没有返回值的方法
        private static void thenAcceptAsync() throws InterruptedException, ExecutionException {
            CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> "Hello");
            future.thenAcceptAsync(System.out::println);
            System.out.println(future.get().length());
        }
        
        private static void thenRunAsync() throws InterruptedException, ExecutionException {
            CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> "Hello");
            future.thenRunAsync(() -> System.out.println("done"));
            System.out.println(future.get());
        }
    }

    测试方法:

    public static void main(String[] args) throws InterruptedException, ExecutionException {
            testWhenComplete();
            testWhenCompleteAsync();
            testThenApply();
            testThenApplyAsync();
            testHandle();
            testHandleAsync();
            thenAcceptAsync();
            thenRunAsync();
            Thread.currentThread().join();
            
        }

    compose 组合、聚合方法

    package com.dwz.executors;
    
    import java.util.concurrent.CompletableFuture;
    import java.util.concurrent.TimeUnit;
    
    public class CompletableFutureExample4 {
        
        private static void sleep(long seconds) {
            try {
                TimeUnit.SECONDS.sleep(seconds);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        
        //两个CompletableFuture同时执行
        private static void testThenAcceptBoth() {
            CompletableFuture.supplyAsync(() -> {
                System.out.println("start the supplyAsync");
                sleep(5);
                System.out.println("end the supplyAsync");
                return "thenAcceptBoth";
            }).thenAcceptBoth(CompletableFuture.supplyAsync(() -> {
                System.out.println("start the thenAcceptBoth");
                sleep(5);
                System.out.println("end the thenAcceptBoth");
                return 100;
            }), (s, i) -> System.out.println(s + "--" + i));
        }
        
        //两个CompletableFuture同时执行,返回其中任意一个的值
        private static void testAcceptEither() {
            CompletableFuture.supplyAsync(() -> {
                System.out.println("start the supplyAsync");
                sleep(5);
                System.out.println("end the supplyAsync");
                return "acceptEither-1";
            }).acceptEither(CompletableFuture.supplyAsync(() -> {
                System.out.println("start the acceptEither");
                sleep(5);
                System.out.println("end the acceptEither");
                return "acceptEither-2";
            }), System.out::println);
        }
        
        //两个CompletableFuture异步执行,action不接收前面CompletableFuture的参数
        private static void testRunAfterBothAsync() {
            CompletableFuture.supplyAsync(() -> {
                System.out.println("start the supplyAsync");
                sleep(5);
                System.out.println("end the supplyAsync");
                return "runAfterBoth-1";
            }).runAfterBothAsync(CompletableFuture.supplyAsync(() -> {
                System.out.println("start the runAfterBoth");
                sleep(3);
                System.out.println("end the runAfterBoth");
                return 100;
            }), () -> System.out.println("DONE"));
        }
        
        //两个CompletableFuture任意一个执行完就开始执行action,action不关心前面CompletableFuture的参数
        private static void testRunAfterEither() {
            CompletableFuture.supplyAsync(() -> {
                System.out.println("start the supplyAsync");
                sleep(5);
                System.out.println("end the supplyAsync");
                return "runAfterEither-1";
            }).runAfterEither(CompletableFuture.supplyAsync(() -> {
                System.out.println("start the runAfterEither");
                sleep(6);
                System.out.println("end the runAfterEither");
                return 100;
            }), () -> System.out.println("DONE"));
        }
        
        //thenCombine跟thenAcceptBoth的区别:
        //thenCombine执行完之后还可以继续往下级联,thenAcceptBoth执行完之后返回的是void不可以继续级联
        private static void testCombine() {
            CompletableFuture.supplyAsync(() -> {
                System.out.println("start the supplyAsync");
                sleep(5);
                System.out.println("end the supplyAsync");
                return "Combine-1";
            }).thenCombine(CompletableFuture.supplyAsync(() -> {
                System.out.println("start the thenCombine");
                sleep(5);
                System.out.println("end the thenCombine");
                return 100;
            }), (s, i) -> s.length() > i).whenComplete((v, t) -> System.out.println(v));
        }
        
        //前一个CompletableFuture的输出作为后一个CompletableFuture的输入,执行完之后还可以继续级联
        private static void testCompose() {
            CompletableFuture.supplyAsync(() -> {
                System.out.println("start the supplyAsync");
                sleep(5);
                System.out.println("end the supplyAsync");
                return "Compose-1";
            }).thenCompose(s -> CompletableFuture.supplyAsync(() -> {
                System.out.println("start the thenCompose");
                sleep(3);
                System.out.println("end the thenCompose");
                return s.length();
            })).thenAccept(System.out::println);
        }
    }

    测试方法:

        public static void main(String[] args) throws InterruptedException {
            testThenAcceptBoth();
            testAcceptEither();
            testRunAfterBothAsync();
            testRunAfterEither();
            testCombine();
            testCompose();
            Thread.currentThread().join();
        }

    terminated 立即结束

    package com.dwz.executors;
    
    import java.util.concurrent.CompletableFuture;
    import java.util.concurrent.ExecutionException;
    import java.util.concurrent.TimeUnit;
    
    public class CompletableFutureExample5 {
        
        private static void sleep(long seconds) {
            try {
                TimeUnit.SECONDS.sleep(seconds);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        
        private static void getNow() throws InterruptedException, ExecutionException {
            CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> {
                sleep(3);
                return "Hello";
            });
            sleep(1);
            String result = future.getNow("World");
            System.out.println(result);
            System.out.println(future.get());
        }
        
        private static void complete() throws InterruptedException, ExecutionException {
            CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> {
                sleep(3);
                System.out.println("--------I will be still process.");
                return "Hello";
            });
            sleep(1);
            boolean finished = future.complete("World");
            System.out.println(finished);
            System.out.println(future.get());
        }
        
        private static void join() {
            CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> {
                sleep(3);
                System.out.println("--------I will be still process.");
                return "Hello";
            });
            String result = future.join();
            System.out.println(result);
        }
        
        private static void completeExceptionally() throws InterruptedException, ExecutionException {
            CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> {
                sleep(3);
                System.out.println("--------I will be still process.");
                return "Hello";
            });
            sleep(5);
            //CompletableFuture没有执行完,快速失败
            //CompletableFuture正常执行完,不抛出异常
            future.completeExceptionally(new RuntimeException());
            System.out.println(future.get());
        }
        
        private static void obtrudeException() throws InterruptedException, ExecutionException {
            CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> {
                sleep(3);
                System.out.println("--------I will be still process.");
                return "Hello";
            });
            //不关心CompletableFuture的值,直接抛出异常
            future.obtrudeException(new Exception("I am error."));
            System.out.println(future.get());
        }
        
        //对错误的处理与业务分开
        private static CompletableFuture<String> errorHandle() {
            CompletableFuture<String> future1 = CompletableFuture.supplyAsync(() -> {
                sleep(3);
                System.out.println("--------I will be still process.");
                return "Hello";
            });
            
            future1.thenApply(s -> {
                Integer.parseInt(s);
                System.out.println("===========keep move============");
                return s + " WORLD";
            }).exceptionally(Throwable::getMessage).thenAccept(System.out::println);
            
            return future1;
        }
    }

    测试方法:

        public static void main(String[] args) throws InterruptedException, ExecutionException {
            getNow();
            complete();
            join();
            completeExceptionally();
            obtrudeException();
            System.out.println(errorHandle().get());
            Thread.currentThread().join();
        }
  • 相关阅读:
    前端笔试题目总结——应用JavaScript函数递归打印数组到HTML页面上
    HTM5新增结构化元素&非结构化元素&新增属性详解
    HTML 5 与HTML 4 的区别
    HTML5框架、背景和实体、XHTML的使用规范
    百度前端笔试题目--css 实现一个带尖角的正方形
    HTML5表单提交和PHP环境搭建
    HTML5列表、块、布局
    HTML5 格式化、样式、链接、表格
    2020-09-13助教一周总结(第二周)
    2020-09-10上课小结
  • 原文地址:https://www.cnblogs.com/zheaven/p/13565872.html
Copyright © 2020-2023  润新知