一、简单用法
1、CompletableFuture实现了Future接口,所以它也具有Future的特性:调用get()方法会阻塞在那,直到结果返回
2、 提交任务:runAsync与supplyAsync
package com.current.flame.aqs.analysis;
import lombok.ToString;
import lombok.extern.slf4j.Slf4j;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
/**
* @author haoxiansheng
*/
@Slf4j
@ToString
public class CompletableFutureExample {
public static void main(String[] args) throws ExecutionException, InterruptedException {
CompletableFutureTest1();
Object obj = CompletableFutureTest2();
log.info("obj=>{}", obj);
}
private static void CompletableFutureTest1() throws ExecutionException, InterruptedException {
CompletableFuture<Void> future = CompletableFuture.runAsync(() -> {
log.info("task CompletableFuture is running ");
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
});
log.info(" future.get1=>{}", future.get());
}
private static Object CompletableFutureTest2() throws ExecutionException, InterruptedException {
CompletableFuture<CompletableFutureExample> future = CompletableFuture.supplyAsync(() -> {
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
return new CompletableFutureExample();
}
);
log.info(" future.get2=>{}", future.get());
return future.get();
}
}
3、CompletableFuture和Future很相似,都可以提交两类任务:一类是无返回值的,另一类是有返回值的。
二、链式的CompletableFuture
Future,在提交任务之后,只能调用get()等结果返回;但对于CompletableFuture,可以在结果上面再加一个callback,当得到结果之后,再接着执行callback
1、thenRun
thenRun后面跟的是一个无参数、无返回值的方法,即Runnable。
2、thenAccept
thenAccept 后面跟的是一个有参数、无返回值的方法,称为Consumer。只进不出=>Consumer;前面的Supplier,是无参数,有返回值,只出不进,Consumer刚好相反。
3、thenApply
thenApply 后面跟的是一个有参数、有返回值的方法,称为Function。
package com.current.flame.aqs;
import lombok.ToString;
import lombok.extern.slf4j.Slf4j;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
/**
* @author haoxiansheng
*/
@Slf4j
@ToString
public class CompletableFutureExample2 {
public static void main(String[] args) throws ExecutionException, InterruptedException {
CompletableFutureThenRun();
CompletableFutureThenAccept();
CompletableFutureThenApply();
}
private static void CompletableFutureThenRun() {
CompletableFuture<Void> thenRun = CompletableFuture.supplyAsync(() -> {
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
return "Success";
}).thenRun(() -> {
log.info("running .....");
});
}
private static void CompletableFutureThenAccept() {
CompletableFuture<Void> thenAccept = CompletableFuture.supplyAsync(()->{
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
return "Success";
}).thenAccept(result ->{
log.info("result=>{}", result);
});
}
private static Object CompletableFutureThenApply() throws ExecutionException, InterruptedException {
CompletableFuture<CompletableFutureExample2> thenApply = CompletableFuture.supplyAsync(()->{
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
return new CompletableFutureExample2();
}).thenApply(result ->{
log.info("result=>{}", result);
return result;
});
return thenApply.get();
}
}
三、 CompletableFuture的组合
1、thenCompose
thenApply接收的是一个Function,但是这个Function的返回值是一个通常的基本数据类型或一个对象,而不是另外一个CompletableFuture。如果Function的返回值也是一个CompletableFuture,就会出现嵌套的CompletableFuture。
package com.current.flame.aqs;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
/**
* @author haoxiansheng
*/
public class CompletableFutureExample3 {
public static void main(String[] args) {
}
private User CompletableFutureTest1(String userId) {
return new User();
}
private Integer CompletableFutureTest1() {
return 1;
}
/**
* @param userId
* @return 返回一个CompletableFuture
*/
private CompletableFuture<User> getUsersDetail(String userId) {
return CompletableFuture.supplyAsync(() -> {
return CompletableFutureTest1(userId);
});
}
private CompletableFuture<Integer> getAge(User user) {
return CompletableFuture.supplyAsync(() -> {
return CompletableFutureTest1();
});
}
private Integer getAge() throws ExecutionException, InterruptedException {
/**
* 方法一
*/
// CompletableFuture<CompletableFuture<Integer>> result = getUsersDetail("").thenApply(user ->getAge(user));
// return result.get().get();
CompletableFuture<Integer> result1 = getUsersDetail("").thenCompose(user -> getAge(user));
return result1.get();
}
static class User {
private Integer age;
public Integer getAge() {
return age;
}
}
}
2、thenCombine