认识和使用CompletableFuture
CompletableFuture是ExecutorService的改进版
首先来了解ExecutorService怎么使用
void executorServiceTest() throws InterruptedException, ExecutionException {
ExecutorService executorService = Executors.newSingleThreadExecutor();
Future<String> future = executorService.submit(() -> {
try {
Thread.sleep(10000L);
return "I am finished.";
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
return "I am Error";
}
});
while(!future.isDone()) {
Thread.sleep(10);
}
System.out.println(future.get());
executorService.shutdown();
}
CompletableFuture对ExecutorService做了简化和改进
使用方式:
private final static Random RANDOM = new Random(System.currentTimeMillis());
public static void main(String[] args) throws Exception {
CompletableFuture<Double> completableFuture = new CompletableFuture<>();
new Thread(() -> {
double value = get();
completableFuture.complete(value);
}).start();
System.out.println("no === block...");
completableFuture.whenComplete((v,t) -> {
System.out.println(v);;
});
}
private static double get() {
try {
Thread.sleep(RANDOM.nextInt(10000));
}catch(Exception e) {
e.printStackTrace();
}
return RANDOM.nextDouble();
}
场景1:连续算5个商品的价格
public class CompletableFutureAPITest {
public static void main(String[] args) {
ExecutorService executorService = Executors.newFixedThreadPool(2, r ->{
Thread t = new Thread(r);
t.setDaemon(false);
return t;
});
List<Integer> productIds = Arrays.asList(1,2,3,4,5);
Stream<CompletableFuture<Double>> completableFutureStream =
productIds.stream().map(i ->
CompletableFuture.supplyAsync(() -> get(i),executorService));
Stream<CompletableFuture<Double>> multiplyFutures = completableFutureStream.map(future -> future.thenApply(CompletableFutureAPITest::mutiply));
List<Double> result = multiplyFutures.map(CompletableFuture::join).collect(Collectors.toList());
System.out.println(result);
}
public static double mutiply(double value) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(value * 10d);
return value * 10d;
}
public static double get(int i) {
try {
Thread.sleep(1000);
}catch(Exception e) {
e.printStackTrace();
}
return i;
}
}
控制台输出:


浙公网安备 33010602011771号