讓天下沒有難學的javajava
點贊、關注、收藏 編程
Future機制是Java 1.5中的引入的,表明着一個異步計算的結果。關於Future/Callable能夠參考多線程
juejin.im/post/5e0819… ,保證你瞬間有了層次感。不至於什麼都會,可是好像又挺糊塗。app
Future解決了Runnable無返回值的問題,提供了2種get()來獲取結果。異步
public interface Future<V>{
//堵塞獲取
V get() throws InterruptedException,ExecutionException;
//等待timeout獲取
V get(long timeout,TimeUnit unit) throws InterruptedException,ExecutionException,TimeoutException;
}
複製代碼
//接受Runnable,無返回值,使用ForkJoinPool.commonPool()線程池
public static CompletableFuture<Void> runAsync(Runnable runnable) //接受Runnable,無返回值,使用指定的executor線程池 public static CompletableFuture<Void> runAsync(Runnable runnable, Executor executor) //接受Supplier,返回U,使用ForkJoinPool.commonPool()線程池 public static <U> CompletableFuture<U> supplyAsync(Supplier<U> supplier) //接受Supplier,返回U,使用指定的executor線程池 public static <U> CompletableFuture<U> supplyAsync(Supplier<U> supplier, Executor executor) 複製代碼
runAsync無返回值 異步編程
supplyAsync有返回值 函數
Stage是階段的意思。顧名思義,CompletionStage它表明了某個同步或者異步計算的一個階段,最終結果上的一個環節。多個CompletionStage構成了一條流水線,一個環節組裝完成了能夠移交給下一個環節。一個結果可能須要流轉了多個CompletionStage。post
如很常見的一個兌換場景,先扣積分、而後發短信、而後設置我的主頁標識,這其中扣積分、發短信、設置標識分別是一個Stage。學習
CompletableFuture鏈式調用背後就是CompletionStage來提供支持,CompletionStage的thenApply().thenApply()...一環扣一環。spa
簡單的CompletionStage,supplyAsync()異步任務執行完後使用thenApply()將結果傳遞給下一個stage。
//這是最簡單也是最經常使用的一個方法,CompletableFuture的鏈式調用
public static void main(String[] args) {
CompletableFuture<String> completableFuture = CompletableFuture.runAsync(() -> {
try {
TimeUnit.SECONDS.sleep(3);
System.out.println("hello");
}catch (Exception e){
e.printStackTrace();
}
}).thenApply(s1 -> {
System.out.println(" big");
return s1 + "big";
}).thenApply(s2 -> " world");
}
//hello big world
複製代碼
thenRun
thenAccept
CompletableFuture<Void> completableFuture = CompletableFuture.supplyAsync(() -> {
try {
TimeUnit.SECONDS.sleep(5);
return "success";
} catch (Exception e) {
e.printStackTrace();
return "error";
}
}).thenAcceptAsync(s->{
if ("success".equals(s)){
System.out.println(s);
}else {
System.err.println(s);
}
});
複製代碼
public <U> CompletableFuture<U> thenCompose(Function<? super T, ? extends CompletionStage<U>> fn) public <U> CompletableFuture<U> thenComposeAsync(Function<? super T, ? extends CompletionStage<U>> fn) public <U> CompletableFuture<U> thenComposeAsync(Function<? super T, ? extends CompletionStage<U>> fn, Executor executor) 複製代碼
CompletableFuture<Integer> future = CompletableFuture.supplyAsync(() -> 1)
.thenCompose(x -> CompletableFuture.supplyAsync(() -> x+1));
複製代碼
thenApply、thenCompose都接受一個Function的函數式接口,那麼區別呢? 1.thenApply使用在同步mapping方法。 2.thenCompose使用在異步mapping方法。
//thenApply
thenApply(Function<? super T,? extends U> fn)
//thenCompose
thenCompose(Function<? super T,? extends CompletableFuture<U>> fn)
//能夠看出thenApply返回的是一個對象U,而thenCompose返回的是CompletableFuture<U>
//從使用角度是來看,若是你第二個操做也是異步操做那麼使用thenCompose,若是是一個簡單同步操做,那麼使用thenApply,相信實戰幾回你就能明白何時使用thenApply、thenCompose。
複製代碼
thenCombine
🌰來了
//從上圖能夠看出,thenCombine的2個CompletableFuture不是依賴關係,第二個CompletableFuture比第一個CompletableFuture先執行,最後的BiFunction()組合2個CompletableFuture結果。
//再次強調:整個流水線是同步的
複製代碼
//2個CompletableFuture處理完成後,將結果進行消費。
//與thenCombine相似,第2個CompletableFuture不依賴第1個CompletableFuture執行完成,返回值Void。
複製代碼
public static CompletableFuture<Void> allOf(CompletableFuture<?>... cfs) 複製代碼
public static void main(String[] args) throws Exception {
long start = System.currentTimeMillis();
CompletableFuture<String> completableFuture1 = CompletableFuture.supplyAsync(() -> {
try {
TimeUnit.SECONDS.sleep(1);
System.out.println("i am sleep 1");
} catch (Exception e) {
e.printStackTrace();
}
return "service 1";
});
CompletableFuture<String> completableFuture2 = CompletableFuture.supplyAsync(() -> {
try {
TimeUnit.SECONDS.sleep(2);
System.out.println("i am sleep 2");
} catch (Exception e) {
e.printStackTrace();
}
return "service 2";
});
CompletableFuture<String> completableFuture3 = CompletableFuture.supplyAsync(() -> {
try {
TimeUnit.SECONDS.sleep(3);
System.out.println("i am sleep 3");
} catch (Exception e) {
e.printStackTrace();
}
return "service 3";
});
CompletableFuture<Void> completableFuture = CompletableFuture
.allOf(completableFuture1, completableFuture2, completableFuture3);
completableFuture.join();
System.out.println(System.currentTimeMillis() - start);
}
複製代碼