• CompletableFuture


    Futrue的缺点有(1)get方法会阻塞 ,(2)不支持注册回调方法 ,(3)不支持级联操作

    CompletableFuture弥补了这些缺点

    public class CompletableFutureTest {
    
        public static void main(String[] args) throws Exception {
    
    //        test1();
    //        test2();
    //        test3();
              test4();
        }
    
    
        //采用了callable+ future方式  ,get方法获取任务的返回值会被阻塞住
        public  static  void  test1() throws  Exception {
            ExecutorService executor = Executors.newCachedThreadPool();
            Future<String> result = executor.submit(()->{
                //模拟执行耗时任务
                System.out.println("task doing...");
                try {
                    Thread.sleep(3000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                //返回结果
                return "result";
            });
            //这里只是将空闲的线程中断,将线程池的状态改为shutdown,不能继续往线程池中添加任务
            executor.shutdown();
            System.out.println("task运行结果" + result.get());
        }
    
        //采用了competableFuture,采用回调的方式获取任务的返回值
        public static void test2() throws Exception {
            //supplyAsync内部使用ForkJoinPool线程池执行任务
            CompletableFuture<String> completableFuture=CompletableFuture.supplyAsync(()->{
                //模拟执行耗时任务
                System.out.println("task doing...");
                try {
                    Thread.sleep(3000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                //返回结果
                return "100";
            }).whenComplete((v,r)->{
                System.out.println("计算结果是: "+v);
            });
            //CompletableFuture里使用的线程池里的线程默认是daemon的。main线程结束后,整个程序也
            //结束了,这里将main线程join后任务里的代码才可以执行完
             Thread.currentThread().join();
        }
    
    
        //compeltableFuture可以支持级联操作
        public static void test3() throws Exception {
            IntStream.range(1,10).boxed().forEach( i ->  CompletableFuture.supplyAsync(CompletableFutureTest::get)
                    .thenAccept(CompletableFutureTest::display)
                    .whenComplete((v,r)->
                        System.out.println(i +" have done")
                    )
            );
            Thread.currentThread().join();
        }
    
        public static  void display(int data){
            int value = ThreadLocalRandom.current().nextInt(10);
            try {
                System.out.println(Thread.currentThread().getName() +"  display  data "+ data+" will sleep "+value);
                TimeUnit.SECONDS.sleep(value);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(Thread.currentThread().getName() +"  dispaly have done  with  data =  "+data);
        }
    
    
        public static  int get(){
            int value = ThreadLocalRandom.current().nextInt(10);
            try {
                System.out.println(Thread.currentThread().getName() +"  get will sleep "+value);
                TimeUnit.SECONDS.sleep(value);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(Thread.currentThread().getName() +"  get have done  "+value);
            return value;
        }
    
        //两个线程分别执行任务,任务都执行完后再执行最后的runnable
        public static void test4() throws InterruptedException {
            CompletableFuture.supplyAsync(Object::new)
                    .thenAcceptAsync(obj -> {
                        try {
                            System.out.println("obj ====== start");
                            TimeUnit.SECONDS.sleep(5);
                            System.out.println("obj ====== " + obj);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
            }).runAfterBoth(CompletableFuture.supplyAsync(() -> "hello")
                    .thenAcceptAsync((v) -> {
                        try {
                            System.out.println("string ====== start");
                            TimeUnit.SECONDS.sleep(3);
                            System.out.println("string ====== " + v);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }), () -> System.out.println("finished"));
            Thread.currentThread().join();
        }
    
    
    
        //一个线程计算奇数和,一个线程计算偶数和,main线程将他们相加
        public static  void test9() throws ExecutionException, InterruptedException {
            CompletableFuture<Integer> oddNumber = CompletableFuture.supplyAsync(()->{
                try {
                    System.out.println("开始计算奇数和  ...");
                    Thread.sleep(3_000);
                    System.out.println("结束计算奇数和  ...");
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                return   1+3+5+7+9;
            });
            CompletableFuture<Integer> evenNumber = CompletableFuture.supplyAsync(()->{
                try {
                    System.out.println("开始计算偶数和  ...");
                    Thread.sleep(5_000);
                    System.out.println("结束计算偶数和  ...");
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                return 2+4+6+8;
            });
            long startTime = System.currentTimeMillis();
            CompletableFuture<Integer> resultFuturn = oddNumber.thenCombine(evenNumber,(odd,even)->{
                return odd + even;
            });
            System.out.println("===============");
            System.out.println("运行结果是:"+resultFuturn.get()+" 总共耗时:"+ (System.currentTimeMillis()-startTime) +"毫秒");
        }
    
    }
  • 相关阅读:
    vue中使用v-bind="$attrs"和v-on="$listeners"进行多层组件监听
    钉钉小程序开发遇到的坑
    promise、async、await、settimeout异步原理与执行顺序
    js获取url参数值的几种方式
    ES6解构赋值
    2019年前端面试题
    浏览器兼容问题踩坑收集
    react+antd分页 实现分页及页面刷新时回到刷新前的page
    无侵入埋点
    CSS学习笔记(三)空白符和换行
  • 原文地址:https://www.cnblogs.com/moris5013/p/11928717.html
Copyright © 2020-2023  润新知