• 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) +"毫秒");
        }
    
    }
    

      

  • 相关阅读:
    什么是大小端
    mina
    出现jar包找不到的问题解决方案
    InnoDB 静态数据加密的常见问题合集
    mysqldump 数据库备份程序,mysqldump 选项合集
    出现The MySQL server is running with the --secure-file-priv option so it cannot问题的原因
    小睡一会,做了一个梦
    IntelliJ IDEA is a solution that appears after importing a project with a clock icon(idea导入项目之后出现时钟的解决方案)
    IntelliJIDE不显示项目文件夹的问题
    夏天的记忆
  • 原文地址:https://www.cnblogs.com/veblen/p/13071689.html
Copyright © 2020-2023  润新知