【HBZ分享】JDK8.x+后的CompletableFuture线程池的使用方式及常用的API--JDK1.8之后才有的
·
CompletableFuture的使用方式及常用的API
介绍
- JDK1.8之前,使用的是Futrue来创建异步线程,这样做比较麻烦。JDK1.8之后,出现了CompletableFuture,内含多种API,使用起来很方便
方法API, CompletabelFuture的静态方法,执行异步任务的API
// 1. 无返回值,默认能使用ForkJoinPool.commonPool() 作为他的线程池执行异步代码
public static CompletableFuture<Void> runAsync(Runnable runnable)
// 2. 无返回值,可以自定义线程池
public static CompletableFuture<Void> runAsync(Runnable runnable)
// 3. 有返回值,默认使用ForkJoinPool.commonPool() 作为他的线程池执行异步代码
public static <U> CompletableFuturn<U> supplyAsync(Supplier<U> supplier)
// 4. 有返回值, 可以自定义线程池
public static <U> CompletableFuture<U> supplyAsync(Supplier<U> supplier, Executor executor)
CompletableFuture对象,获取结果API
// 1. 如果返回值没有返回,则一直阻塞
V get();
// 2. 设置等待超时时间
V get(Long timeout, Timeout unit)
// 3. 有返回值就返回,线程抛出异常就返回设置的默认值
T getNow(T defaultValue);
CompletableFuture对象,其他重点API
// 1. 无返回值,当前任务正常完成以后执行,当前任务的执行结果可以作为下一个任务的输入参数
thenAccept
// 2. 有返回值,当前任务正常完成以后,当前任务执行的结果会作为下一个任务的输入参数
thenApply
// 3. 对不关心上一步的计算结果,执行下一个操作
thenRun
案例
1. 【有返回值】,默认使用ForkJoinPool.commonPool() 作为他的线程池执行异步代码
/**
* 【有返回值】,【supplyAsync】测试,默认使用ForkJoinPool.commonPool() 作为他的线程池执行异步代码
*/
@Test
public void normalCompletableFutureTest() throws ExecutionException, InterruptedException {
CompletableFuture<String> normalCompletableFuture = CompletableFuture.supplyAsync(() -> {
try {
TimeUnit.SECONDS.sleep(5);
} catch (InterruptedException e) {
e.printStackTrace();
}
return "测试normalCompletableFutureTest";
});
System.out.println("get()方法,一直阻塞到出结果位置" + normalCompletableFuture.get());
System.out.println("get(Long timeout, TimeUnit time)方法,设置阻塞时间,过期抛异常" + normalCompletableFuture.get(1, TimeUnit.SECONDS));
}
返回结果:get()方法,一直阻塞到出结果位置测试normalCompletableFutureTest
2. 有返回值,当前任务正常完成以后,当前任务执行的结果会作为下一个任务的输入参数【thenApply】
/**
* 【有返回值】,默认使用ForkJoinPool.commonPool() 作为他的线程池执行异步代码
*/
@Test
public void thenApplyTest() throws ExecutionException, InterruptedException, TimeoutException {
CompletableFuture<String> normalCompletableFuture = CompletableFuture.supplyAsync(() -> {
try {
TimeUnit.SECONDS.sleep(5);
} catch (InterruptedException e) {
e.printStackTrace();
}
return "测试normalCompletableFutureTest";
});
// 用上一次任务的返回值normalCompletableFuture 去调用thenApply方法,参数是element, element就是上一次任务的结果
CompletableFuture<String> thenApplyFuture = normalCompletableFuture.thenApply((element) -> {
System.out.println("入参:" + element);
System.out.println("执行任务2...");
return "这是第二个任务";
});
System.out.println("get()方法,一直阻塞到出结果位置" + thenApplyFuture.get());
}
返回结果:入参:测试normalCompletableFutureTest
执行任务2...
get()方法,一直阻塞到出结果位置:这是第二个任务
3. 无返回值,当前任务正常完成以后执行,当前任务的执行结果可以作为下一个任务的输入参数【thenAccept】
/**
* 【有返回值】,默认使用ForkJoinPool.commonPool() 作为他的线程池执行异步代码
*/
@Test
public void thenAcceptTest() throws ExecutionException, InterruptedException, TimeoutException {
CompletableFuture<String> normalCompletableFuture = CompletableFuture.supplyAsync(() -> {
try {
TimeUnit.SECONDS.sleep(5);
} catch (InterruptedException e) {
e.printStackTrace();
}
return "测试normalCompletableFutureTest";
});
// 用上一次任务的返回值normalCompletableFuture 去调用thenApply方法,参数是element, element就是上一次任务的结果
CompletableFuture<Void> thenAcceptFuture = normalCompletableFuture.thenAccept((element) -> {
System.out.println("入参:" + element);
System.out.println("执行任务2...");
});
// thenAcceptFuture.get() 返回结果会是 null, 因为无返回值
System.out.println("get()方法,一直阻塞到出结果位置" + thenAcceptFuture.get());
}
返回结果:入参:测试normalCompletableFutureTest
执行任务2...
get()方法,一直阻塞到出结果位置:null
更多推荐



所有评论(0)