异步化:并行方案得以实施的基础,利用多线程优化性能这个核心方案得以实施的基础。
task is cheap show your code!
package com.zy.concurrent.future;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.TimeUnit;
/**
* @author zy1994
* @Classname CompletableFutureDemo
* @Date 2019-06-17
*/
public class CompletableFutureDemo {
public static void main(String[] args) {
//刷锅 烧水
CompletableFuture<Void> f1 =
CompletableFuture.runAsync(()->{
System.out.println("T1 :刷锅....");
sleep(1,TimeUnit.SECONDS);
System.out.println("T1 :烧开水....");
sleep(1,TimeUnit.SECONDS);
});
//task 1 洗菜 洗碗 准备面条
CompletableFuture<String> f2 =
CompletableFuture.supplyAsync(()->{
System.out.println("T2 :洗菜....");
sleep(1,TimeUnit.SECONDS);
System.out.println("T2 :洗碗....");
sleep(1,TimeUnit.SECONDS);
System.out.println("T2 :拿面条....");
sleep(1,TimeUnit.SECONDS);
return "龙须面";
});
CompletableFuture<String> f3 =
f1.thenCombine(f2,(__,tf)->{
return "开饭----热腾腾的"+tf;
});
System.out.println(f3.join());
}
private static void sleep(int i, TimeUnit seconds) {
try {
seconds.sleep(i);
}catch (Exception e){
//do something
}
}
}
CompletableFuturer四个核心的静态方法
使用默认的线程池 使用的是公共的ForkJoinPool线程池。默认创建的线程数就是cpu的核数。
最好不要使用公共的线程池,最好根据不同的业务创建不同的线程池,防止相互干扰,造成线程饥饿。
public static CompletableFuture<Void> runAsync(Runnable runnable) {
return asyncRunStage(asyncPool, runnable);
}
public static <U> CompletableFuture<U> supplyAsync(Supplier<U> supplier) {
return asyncSupplyStage(asyncPool, supplier);
}
使用自定义的线程池
public static CompletableFuture<Void> runAsync(Runnable runnable,
Executor executor) {
return asyncRunStage(screenExecutor(executor), runnable);
}
public static <U> CompletableFuture<U> supplyAsync(Supplier<U> supplier,
Executor executor) {
return asyncSupplyStage(screenExecutor(executor), supplier);
}
对于异步操作需要关心的两个重点问题
CompletionStage接口
串行
thenApply
public <U> CompletionStage<U> thenApply(Function<? super T,? extends U> fn);
thenAccept
public CompletionStage<Void> thenAccept(Consumer<? super T> action);
thenRun
public CompletionStage<Void> thenRun(Runnable action);
thenCompose
public <U> CompletionStage<U> thenCompose
(Function<? super T, ? extends CompletionStage<U>> fn);
CompletableFuture<String> ff = CompletableFuture.supplyAsync(() -> "i Love I")
.thenApply(v -> v + "NB")
.thenApply(String::toLowerCase);
System.out.println(ff.join());
And汇聚
CompletionStage<R> thenCombine(other, fn);
CompletionStage<R> thenCombineAsync(other, fn);
CompletionStage<Void> thenAcceptBoth(other, consumer);
CompletionStage<Void> thenAcceptBothAsync(other, consumer);
CompletionStage<Void> runAfterBoth(other, action);
CompletionStage<Void> runAfterBothAsync(other, action);
or汇聚
CompletionStage applyToEither(other, fn);
CompletionStage applyToEitherAsync(other, fn);
CompletionStage acceptEither(other, consumer);
CompletionStage acceptEitherAsync(other, consumer);
CompletionStage runAfterEither(other, action);
CompletionStage runAfterEitherAsync(other, action);
CompletableFuture<String> stringCompletableFuture = CompletableFuture.supplyAsync(() -> {
int ss = getRandom(3, 8);
sleep(ss, TimeUnit.SECONDS);
return String.valueOf(ss);
});
CompletableFuture<String> stringCompletableFuture1 = CompletableFuture.supplyAsync(() -> {
int ss = getRandom(3, 8);
sleep(ss, TimeUnit.SECONDS);
return String.valueOf(ss);
});
CompletableFuture<String> stringCompletableFuture2 = stringCompletableFuture.applyToEither(stringCompletableFuture1, s -> s);
System.out.println(stringCompletableFuture2.join());
}
/**
* 生成开始到结束的一个随机数
* @param begin
* @param end
* @return
*/
public static int getRandom(int begin,int end){
return (int)(begin+ Math.random()*(end-begin+1));
}
public static void exceptionHandler(){
CompletableFuture<Integer> exceptionally = CompletableFuture.supplyAsync(() -> 1 / 0)
.exceptionally(e -> {
System.out.println(e);
return 0;
}).whenComplete((u,t)->{
System.out.println("finally"+t);
});
}