CompletableFuture<T>

CompletableFuture是java8的新特性:異步編程。
直接上代碼(詳細(xì)說明在代碼中):

package com.example.java8.chapter11;

import java.util.concurrent.CompletableFuture;
import java.util.concurrent.TimeUnit;
import org.junit.Test;

/**
 * 提醒:下面每個方法最后幾行注釋的代碼是此方法在執(zhí)行時,在console打印的內(nèi)容
 */
public class FutureTest {
    
    public void delay(int second) {
        long time = second * 1000;
        try {
            Thread.sleep(time);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
    
    public String thing1() {
        delay(1);
        System.out.println("thing1:方法執(zhí)行中");
        return "thing1返回值";
    }
    
    public Integer thing2() {
        delay(2);
        System.out.println("thing2:方法執(zhí)行中");
        return 100;
    }
    
    public String thing3() {
        delay(3);
        System.out.println("thing3:方法執(zhí)行中");
        return "thing3返回值";
    }
    
    public String thing4(String text) {
        delay(4);
        System.out.println("參數(shù):" + text);
        System.out.println("thing4:方法執(zhí)行中");
        return "thing4返回值";
    }
    
    /**有返回結(jié)果的異步執(zhí)行*/
    @Test
    public void test1() throws Exception {
        // 1.異步執(zhí)行,重新起一個線程去執(zhí)行新的任務(wù)
        CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> thing1());
        // 2.獲取異步執(zhí)行的結(jié)果,限定時間在2秒內(nèi)(避免無限期等待;如果超過2秒,就會拋出Timeout異常)
        String text = future.get(2L, TimeUnit.SECONDS);
        // 3.打印結(jié)果
        System.out.println("結(jié)果:" + text);
//      thing1:方法執(zhí)行中
//      結(jié)果:thing1返回值
    }
    
    /**無返回結(jié)果的異步執(zhí)行*/
    @Test
    public void test2() throws Exception {
        // join方法是為了獲取結(jié)果;如果不關(guān)注結(jié)果,可以不調(diào)用join方法(異步線程也會執(zhí)行)
        // get方法和join方法效果一樣;
        // get(Long time) 帶參數(shù)的get方法表示設(shè)置超時,建議使用設(shè)置超時的get獲取異步執(zhí)行結(jié)果
        CompletableFuture.runAsync(() -> thing1()).join();
//      thing1:方法執(zhí)行中
    }
    
    @Test
    public void test3() {
        // 等待第一個異步執(zhí)行完畢后,得到異步執(zhí)行結(jié)果繼續(xù)執(zhí)行,沒有返回值
        CompletableFuture<Void> accept = CompletableFuture.supplyAsync(() -> thing1())
                .thenAccept(e -> System.out.println("包裝結(jié)果:" + e));
        accept.join();
//      thing1:方法執(zhí)行中
//      包裝結(jié)果:thing1返回值
    }
    
    @Test
    public void test4() {
        // 等待第一個方法執(zhí)行完畢,然后第二方法執(zhí)行完畢,接著處理方法1和方法2的結(jié)果,沒有返回值
        CompletableFuture<Void> acceptBoth = CompletableFuture.supplyAsync(() -> thing1())
                .thenAcceptBoth(CompletableFuture.supplyAsync(() -> thing3()), (e1, e2) -> System.out.println(e1 +" "+ e2));
        acceptBoth.join();
//      thing1:方法執(zhí)行中
//      thing3:方法執(zhí)行中
//      thing1返回值 thing3返回值
    }
    
    @Test
    public void test5() {
        // 等待第一個異步執(zhí)行完畢后,得到異步執(zhí)行結(jié)果繼續(xù)執(zhí)行,有返回值(和thenAccept相似,區(qū)別就是有返回值)
        CompletableFuture<Integer> thenApply = CompletableFuture.supplyAsync(() -> thing1())
                .thenApply((t) -> {
                    System.out.println(t);
                    return 999;
                });
        thenApply.join();
//      thing1:方法執(zhí)行中
//      thing1返回值
    }
    
    @Test
    public void test6() {
        // 等待第一個方法執(zhí)行完畢,然后第二方法執(zhí)行完畢,接著處理方法1和方法2的結(jié)果,有返回值(和thenAcceptBoth相似,區(qū)別就是有返回值)
        CompletableFuture<String> thenCombine = CompletableFuture.supplyAsync(() -> thing1())
                .thenCombine(CompletableFuture.supplyAsync(() -> thing2()), (e1, e2) -> {
                    System.out.println("e1:" + e1);
                    System.out.println("e2:" + e2);
                    return "java";
                });
        thenCombine.join();
//      thing1:方法執(zhí)行中
//      thing2:方法執(zhí)行中
//      e1:thing1返回值
//      e2:100
    }
    
    @Test
    public void test7() {
        // 異步方法1執(zhí)行完畢后,方法1的結(jié)果傳遞給方法2繼續(xù)執(zhí)行
        CompletableFuture<String> thenCompose = CompletableFuture.supplyAsync(() -> thing1())
                .thenCompose(e -> CompletableFuture.supplyAsync(() -> thing4(e)));
        thenCompose.join();
//      thing1:方法執(zhí)行中
//      參數(shù):thing1返回值
//      thing4:方法執(zhí)行中
    }
    
    @Test
    public void test8() {
        // 異步方法1執(zhí)行完畢后,再執(zhí)行1個action
        CompletableFuture.supplyAsync(() -> thing1()).thenRun(() -> System.out.println("執(zhí)行中")).join();
//      thing1:方法執(zhí)行中
//      執(zhí)行中
    }
    
    @Test
    public void test9() {
        // 一個異步方法執(zhí)行完畢后,得到他的返回結(jié)果和異常信息進(jìn)一步處理,最后返回方法1返回結(jié)果
        String join = CompletableFuture.supplyAsync(() -> thing1()).whenComplete((e1, e2) -> {
            System.out.println("e1: 異步請求的結(jié)果:" + e1);
            System.out.println("e2: 異常:" + e2);
        }).join();
        System.out.println(join);
//      thing1:方法執(zhí)行中
//      e1: 異步請求的結(jié)果:thing1返回值
//      e2: 異常:null
//      thing1返回值
    }
    
    @Test
    public void test10() {
        // 一個異步方法執(zhí)行完畢后,得到他的返回結(jié)果和異常信息進(jìn)一步處理,最后返回其他類型的結(jié)果
        CompletableFuture<Integer> handle = CompletableFuture.supplyAsync(() -> thing1()).handle((e1, e2) -> {
            System.out.println("e1: 異步請求的結(jié)果:" + e1);
            System.out.println("e2: 異常:" + e2);
            return 300;
        });
        Integer i = handle.join();
        System.out.println(i);
//      thing1:方法執(zhí)行中
//      e1: 異步請求的結(jié)果:thing1返回值
//      e2: 異常:null
//      300
    }

}

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容