1.意义
回调方式的异步编程,弥补Future获取结果的不便。
2.常用方法
ForkJoinPool.commonPool() 作为默认线程池。而ForkJoinPool里面的线程都是daemon线程,主线程跑完了,虚拟机也就over了。
CompletableFuture中用到的接口很多是函数式接口,建议先学java8相关内容。
2.1 supplyAsync
有返回值CompletableFuture;(如线程池的sumit())
示例:
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.TimeUnit;
public class CompletableFutureTest {
public static void main(String[] args) throws Exception {
//返回一个String类型的CompletableFuture
CompletableFuture<String> completableFutureA = CompletableFuture.supplyAsync(() -> {
return "String1";
});
System.out.println(completableFutureA.get());
源码:
public static <U> CompletableFuture<U> supplyAsync(Supplier<U> supplier) {
return asyncSupplyStage(asyncPool, supplier);
}
static <U> CompletableFuture<U> asyncSupplyStage(Executor e,
Supplier<U> f) {
if (f == null) throw new NullPointerException();
CompletableFuture<U> d = new CompletableFuture<U>();
e.execute(new AsyncSupply<U>(d, f));
return d;
}
private static final Executor asyncPool = useCommonPool ?
ForkJoinPool.commonPool() : new ThreadPerTaskExecutor();
2.2 runAsync
异步执行某个任务,没有返回值。(如线程池的excute() )
CompletableFuture.runAsync(()->{
System.out.println("异步执行某个任务");
});
2.3 get
get()阻塞方法,获取CompletableFuture的值;
getNow(T valueIfAbsent),非阻塞方法,获取不到CompletableFuture的值,直接返回valueIfAbsent。但当ComletableFuture完成后返回的是“String1”
get(long timeout, TimeUnit unit)等到指定时间获取不到CompletableFuture的值,直接报错。
CompletableFuture<String> completableFuture2 = CompletableFuture.supplyAsync(() -> {
return "String2";
}).whenCompleteAsync((v, t) -> {//异步执行
try {
TimeUnit.SECONDS.sleep(5);
System.out.println("demo2");
} catch (Exception e) {
}
});
//System.out.println(completableFuture2.get());
System.out.println(completableFuture2.getNow("String2NotGet"));
System.out.println(completableFuture2.get(3,TimeUnit.SECONDS));
2.4 complete
complete(T value)判断任务是否执行完毕,未执行完毕将CompletableFuture的值设为value。而且completableFuture2完成后也是返回“xx”.
CompletableFuture<String> completableFuture2 = CompletableFuture.supplyAsync(() -> {
return "String2";
}).whenCompleteAsync((v, t) -> {//异步执行
try {
TimeUnit.SECONDS.sleep(1);
System.out.println("demo2");
} catch (Exception e) {
}
});
System.out.println("222222222222222222");
boolean flag = completableFuture2.complete("xx");
System.out.println(flag);
System.out.println(completableFuture2.get());
2.4 whenComplete && whenCompleteAsync
whenComplete: 上面的线程继续执行
whenCompleteAsync: 交给线程池去做
当任务执行完成时,调用该方法。
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.TimeUnit;
public class CompletableFutureTest {
public static void main(String[] args) throws Exception {
//返回一个String类型的CompletableFuture
CompletableFuture<String> completableFutureA = CompletableFuture.supplyAsync(() -> {
return "String1";
});
System.out.println(completableFutureA.get());
CompletableFuture<String> completableFuture = CompletableFuture.supplyAsync(() -> {
return "String1";
}).whenComplete((v, t) -> {//同步执行
try {
TimeUnit.SECONDS.sleep(3);
System.out.println("demo1");
} catch (Exception e) {
}
});
System.out.println("11111111111111111");
CompletableFuture<String> completableFuture2 = CompletableFuture.supplyAsync(() -> {
return "String2";
}).whenCompleteAsync((v, t) -> {//异步执行
try {
TimeUnit.SECONDS.sleep(1);
System.out.println("demo2");
} catch (Exception e) {
}
});
System.out.println(completableFuture2.getNow("String2NotGet"));
CompletableFuture<Integer> completableFuture3 = CompletableFuture.supplyAsync(() -> {
return "String3";
}).thenApply(String::length);
System.out.println(completableFuture3.get());
System.out.println("do other");
Thread.currentThread().join();
}
}
2.5 exceptionally
任务执行抛出异常后,所要执行的方法。
无异常,执行whenCompleteAsync的方法则完成。
import java.util.concurrent.*;
public class CompletableFutureTest {
public static void main(String[] args) throws Exception {
CompletableFuture<String> completableFuture = CompletableFuture.supplyAsync(() -> {
// int i = 1 / 0;
return "String1";
}).whenCompleteAsync((v, t) -> {//同步执行
System.out.println("完成");
}).exceptionally(e -> {
System.out.println("有异常");
return "e";
});
System.out.println(completableFuture.get());
Thread.currentThread().join();
}}
有异常,执行whenCompleteAsync的方法之后,再执行exceptionally方法,并将completableFuture 的值替换为exceptionally返回的值。
import java.util.concurrent.*;
public class CompletableFutureTest {
public static void main(String[] args) throws Exception {
CompletableFuture<String> completableFuture = CompletableFuture.supplyAsync(() -> {
int i = 1 / 0;
return "String1";
}).whenCompleteAsync((v, t) -> {//同步执行
System.out.println("完成");
}).exceptionally(e -> {
System.out.println("有异常");
return "e";
});
System.out.println(completableFuture.get());
Thread.currentThread().join();
}}
2.6 thenApply && handle
任务出现异常thenApply不执行
import java.util.concurrent.*;
public class CompletableFutureTest {
public static void main(String[] args) throws Exception {
CompletableFuture<String> completableFuture2 = CompletableFuture.supplyAsync(() -> {
System.out.println("22222222222222");
int i = 1 / 0;//有异常,直接停止;不执行thenApply方法
System.out.println("22222222222222");
return "String2";
}).thenApply(t -> {//有异常不再执行
System.out.println(t);
return t + "Apply";
});
Thread.currentThread().join();
}}
有异常(之前的方法不捕获异常),handle可以捕获异常;并将handle返回的值赋值给completableFuture。
import java.util.concurrent.*;
public class CompletableFutureTest {
public static void main(String[] args) throws Exception {
CompletableFuture<String> completableFuture3 = CompletableFuture.supplyAsync(() -> {
System.out.println(3333333);
int i = 1 / 0; //有异常,直接执行handle;并将handle返回的值赋值给completableFuture3
System.out.println(3333333);
return "String3";
}).handle((v, t) -> {
System.out.println(v);
return "handle";
});
System.out.println(completableFuture3.get());
Thread.currentThread().join();
}}
2.7 allOf
组合多个CompletableFuture
import java.util.concurrent.*;
public class CompletableFutureTest {
public static void main(String[] args) throws Exception {
CompletableFuture<String> completableFuture2 = CompletableFuture.supplyAsync(() -> {
return "String2";
}).thenApply(t -> {
try {
TimeUnit.SECONDS.sleep(3);
System.out.println(t);
}catch (Exception e){
}
return t + "Apply";
});
CompletableFuture<String> completableFuture3 = CompletableFuture.supplyAsync(() -> {
return "String3";
}).handle((v, t) -> {
try {
TimeUnit.SECONDS.sleep(3);
}catch (Exception e){
}
System.out.println(v);
return t + "handle";
});
CompletableFuture<String> completableFuture4 = CompletableFuture.supplyAsync(() -> {
return "String4";
});
CompletableFuture.allOf(completableFuture3,completableFuture4,completableFuture2).whenComplete((v,t)->{
try {//集中监听所有任务执行结束与否,全部执行完才执行whenComplete
System.out.println("--------------all of---------------");
System.out.println(completableFuture2.get()+completableFuture3.get()+completableFuture4.get());
System.out.println("--------------all of---------------");
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
});
Thread.currentThread().join();
}
}