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

}

  


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM