https://www.cnblogs.com/houzheng/p/10964314.html
package cn.hou.completablefuture;
import org.junit.Test;
import java.util.concurrent.*;
public class CompletableFutureDemo {
/**
* 在Java8中,CompletableFuture提供了非常強大的Future的擴展功能,可以幫助我們簡化異步編程的複雜性,
* 並且提供了函數式編程的能力,可以通過回調的方式處理計算結果,也提供了轉換和組合 CompletableFuture 的方法
*
* 注意: 方法中有Async一般表示另起一個線程,沒有表示用當前線程
*/
@Test
public void test01() throws Exception {
ExecutorService service = Executors.newFixedThreadPool(5);
/**
* supplyAsync用於有返回值的任務,
* runAsync則用於沒有返回值的任務
* Executor參數可以手動指定線程池,否則默認ForkJoinPool.commonPool()系統級公共線程池
*/
CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> {
try {
TimeUnit.SECONDS.sleep(3);
} catch (InterruptedException e) {
e.printStackTrace();
}
return "侯徵";
}, service);
CompletableFuture<Void> data = CompletableFuture.runAsync(() -> System.out.println("侯徵"));
/**
* 計算結果完成回調
*/
future.whenComplete((x,y)-> System.out.println(x+","+y)); //執行當前任務的線程執行繼續執
data.whenCompleteAsync((x,y)-> System.out.println(x+","+y)); // 交給線程池另起線程執行
future.exceptionally(Throwable::toString);
//System.out.println(future.get());
/**
* thenApply,一個線程依賴另一個線程可以使用,出現異常不執行
*/
//第二個線程依賴第一個的結果
CompletableFuture<Integer> future1 = CompletableFuture.supplyAsync(() -> 5).thenApply(x -> x);
/**
* handle 是執行任務完成時對結果的處理,第一個出現異常繼續執行
*/
CompletableFuture<Integer> future2 = future1.handleAsync((x, y) -> x + 2);
System.out.println(future2.get());//7
/**
* thenAccept 消費處理結果,不返回
*/
future2.thenAccept(System.out::println);
/**
* thenRun 不關心任務的處理結果。只要上面的任務執行完成,就開始執行
*/
future2.thenRunAsync(()-> System.out.println("繼續下一個任務"));
/**
* thenCombine 會把 兩個 CompletionStage 的任務都執行完成後,兩個任務的結果交給 thenCombine 來處理
*/
CompletableFuture<Integer> future3 = future1.thenCombine(future2, Integer::sum);
System.out.println(future3.get()); // 5+7=12
/**
* thenAcceptBoth : 當兩個CompletionStage都執行完成後,把結果一塊交給thenAcceptBoth來進行消耗
*/
future1.thenAcceptBothAsync(future2,(x,y)-> System.out.println(x+","+y)); //5,7
/**
* applyToEither
* 兩個CompletionStage,誰執行返回的結果快,我就用那個CompletionStage的結果進行下一步的轉化操作
*/
CompletableFuture<Integer> future4 = future1.applyToEither(future2, x -> x);
System.out.println(future4.get()); //5
/**
* acceptEither
* 兩個CompletionStage,誰執行返回的結果快,我就用那個CompletionStage的結果進行下一步的消耗操作
*/
future1.acceptEither(future2, System.out::println);
/**
* runAfterEither
* 兩個CompletionStage,任何一個完成了都會執行下一步的操作(Runnable
*/
future1.runAfterEither(future,()-> System.out.println("有一個完成了,我繼續"));
/**
* runAfterBoth
* 兩個CompletionStage,都完成了計算纔會執行下一步的操作(Runnable)
*/
future1.runAfterBoth(future,()-> System.out.println("都完成了,我繼續"));
/**
* thenCompose 方法
* thenCompose 方法允許你對多個 CompletionStage 進行流水線操作,第一個操作完成時,將其結果作爲參數傳遞給第二個操作
* thenApply是接受一個函數,thenCompose是接受一個future實例,更適合處理流操作
*/
future1.thenComposeAsync(x->CompletableFuture.supplyAsync(()->x+1))
.thenComposeAsync(x->CompletableFuture.supplyAsync(()->x+2))
.thenCompose(x->CompletableFuture.runAsync(()-> System.out.println("流操作結果:"+x)));
TimeUnit.SECONDS.sleep(5);//主線程sleep,等待其他線程執行
}
}