一、创建CompletableFuture的方式
1、同步
CompletableFuture<String> cf = new CompletableFuture<>();
cf.complete("result");
CompletableFuture<String> cf = CompletableFuture.completedFuture("result");
2、异步
ExecutorService executor = Executors.newSingleThreadExecutor();
CompletableFuture<Void> cf = CompletableFuture.runAsync(() -> {});
CompletableFuture<Void> cf = CompletableFuture.runAsync(() -> {}, executor);
CompletableFuture<String> cf = CompletableFuture.supplyAsync(() -> "result");
CompletableFuture<String> cf = CompletableFuture.supplyAsync(() -> "result", executor);
二、获取异步执行结果
1、get()
CompletableFuture<String> cf = CompletableFuture.supplyAsync(() -> {
return "result";
});
try {
String result = cf.get();
} catch (InterruptedException e) {
throw new RuntimeException(e);
} catch (ExecutionException e) {
throw new RuntimeException(e);
}
2、get(long timeout, TimeUnit unit)
CompletableFuture<String> cf = CompletableFuture.supplyAsync(() -> {
return "result";
});
try {
String result = cf.get(1, TimeUnit.SECONDS);
} catch (TimeoutException e) {
System.out.println("超时");
} catch (ExecutionException e) {
throw new RuntimeException(e);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
3、join()
CompletableFuture<String> cf = CompletableFuture.supplyAsync(() -> {
return "result";
});
String result = cf.join()
4、getNow(T valueIfAbsent)
CompletableFuture<String> cf = CompletableFuture.supplyAsync(() -> {
return "result";
});
String result = cf.getNow("result2")
三、对执行结果进行处理
xxx() 如果注册时被依赖的操作已经执行完成,则直接由当前线程执行、如果注册时被依赖的操作还未执行完,则由回调线程执行。
xxxAsync() 使用从默认线程(ForkJoinPool 线程池)执行当前任务
xxxAsync(Executor executor) 使用自己指定的线程池执行当前任务
1、thenRun() - 串行
CompletableFuture<String> cf = CompletableFuture.supplyAsync(() -> "result1");
cf.thenRun(() -> {
System.out.println("结束后执行");
System.out.println(Thread.currentThread().getName());
});
2、thenAccept() - 串行
CompletableFuture<String> cf = CompletableFuture.supplyAsync(() -> "result1");
cf.thenAccept(res -> {
System.out.println(res);
System.out.println(Thread.currentThread().getName());
});
3、thenApply() - 串行
CompletableFuture<String> cf = CompletableFuture.supplyAsync(() -> "result1");
cf.thenApply(res -> {
System.out.println(res);
System.out.println(Thread.currentThread().getName());
return "result2";
}).whenComplete((res, ex) -> {
System.out.println(res);
});
4、whenComplete() - 异常处理
CompletableFuture<String> cf = CompletableFuture.supplyAsync(() -> "result1");
cf.whenComplete((res, ex) -> {
System.out.println("执行结果: " + res);
System.out.println(Thread.currentThread().getName());
ex.printStackTrace();
});
5、handle()、exceptionally() - 异常处理
CompletableFuture.supplyAsync(() -> {
int a = 1 / 0;
return "result1";
}).exceptionally(ex -> {
System.out.println(ex);
return "error";
}).handle((res, ex) -> {
System.out.println(res);
System.out.println(ex);
return "handle";
}).thenAccept(res -> {
System.out.println(res);
});
6、thenCompose() - 串行
CompletableFuture<String> cf1 = CompletableFuture.supplyAsync(() -> {
try {
TimeUnit.MILLISECONDS.sleep(3000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
return "result1";
});
StopWatch sw = StopWatch.createStarted();
CompletableFuture<String> cm = cf1.thenCompose(res -> {
System.out.println(res);
return CompletableFuture.supplyAsync(() -> {
try {
TimeUnit.MILLISECONDS.sleep(6000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
return res + "result2";
});
});
System.out.println(cm.join());
System.out.println("耗时:" + sw.getTime(TimeUnit.MILLISECONDS));
7、applyToEither() - OR汇聚
CompletableFuture<String> cf1 = CompletableFuture.supplyAsync(() -> {
try {
TimeUnit.MILLISECONDS.sleep(4000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
return "result1";
});
CompletableFuture<String> cf2 = CompletableFuture.supplyAsync(() -> {
try {
TimeUnit.MILLISECONDS.sleep(3000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
return "result2";
});
StopWatch sw = StopWatch.createStarted();
CompletableFuture<String> cm = cf1.applyToEither(cf2, (res) -> {
return res;
});
System.out.println(cm.join());
System.out.println("耗时:" + sw.getTime(TimeUnit.MILLISECONDS));
8、runAfterEither() - OR汇聚
CompletableFuture<String> cf1 = CompletableFuture.supplyAsync(() -> {
try {
TimeUnit.MILLISECONDS.sleep(4000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
return "result1";
});
CompletableFuture<String> cf2 = CompletableFuture.supplyAsync(() -> {
try {
TimeUnit.MILLISECONDS.sleep(3000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
return "result2";
});
StopWatch sw = StopWatch.createStarted();
CompletableFuture<Void> cm = cf1.runAfterEither(cf2, () -> {
System.out.println("执行结束了");
});
cm.join();
System.out.println("耗时:" + sw.getTime(TimeUnit.MILLISECONDS));
9、thenCombine() - AND汇聚
CompletableFuture<String> cf1 = CompletableFuture.supplyAsync(() -> {
try {
TimeUnit.MILLISECONDS.sleep(3000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
return "result1";
});
CompletableFuture<String> cf2 = CompletableFuture.supplyAsync(() -> {
try {
TimeUnit.MILLISECONDS.sleep(6000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
return "result2";
});
StopWatch sw = StopWatch.createStarted();
CompletableFuture<String> cm = cf1.thenCombine(cf2, (res1, res2) -> {
return res1 + res2;
});
String result = cm.join();
System.out.println(result);
System.out.println("耗时:" + sw.getTime(TimeUnit.MILLISECONDS));
10、runAfterBoth() - AND汇聚
CompletableFuture<String> cf1 = CompletableFuture.supplyAsync(() -> {
try {
TimeUnit.MILLISECONDS.sleep(3000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
return "result1";
});
CompletableFuture<String> cf2 = CompletableFuture.supplyAsync(() -> {
try {
TimeUnit.MILLISECONDS.sleep(6000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
return "result2";
});
StopWatch sw = StopWatch.createStarted();
CompletableFuture<Void> cm = cf1.runAfterBoth(cf2, () -> {
System.out.println("执行结束");
});
cm.join();
System.out.println("耗时:" + sw.getTime(TimeUnit.MILLISECONDS));
11、多任务组合
CompletableFuture<String> cf1 = CompletableFuture.supplyAsync(() -> {
try {
TimeUnit.MILLISECONDS.sleep(1000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
return "result1";
});
CompletableFuture<String> cf2 = CompletableFuture.supplyAsync(() -> {
try {
TimeUnit.MILLISECONDS.sleep(2000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
return "result2";
});
CompletableFuture<String> cf3 = CompletableFuture.supplyAsync(() -> {
try {
TimeUnit.MILLISECONDS.sleep(3000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
return "result3";
});
StopWatch sw = StopWatch.createStarted();
CompletableFuture<Void> cf = CompletableFuture.allOf(cf1, cf2, cf3);
cf.join();
System.out.println(cf1.join());
System.out.println(cf2.join());
System.out.println(cf3.join());
System.out.println("耗时:" + sw.getTime(TimeUnit.MILLISECONDS));
CompletableFuture<String> cf1 = CompletableFuture.supplyAsync(() -> {
try {
TimeUnit.MILLISECONDS.sleep(1000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
return "result1";
});
CompletableFuture<String> cf2 = CompletableFuture.supplyAsync(() -> {
try {
TimeUnit.MILLISECONDS.sleep(2000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
return "result2";
});
CompletableFuture<String> cf3 = CompletableFuture.supplyAsync(() -> {
try {
TimeUnit.MILLISECONDS.sleep(3000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
return "result3";
});
StopWatch sw = StopWatch.createStarted();
CompletableFuture<Object> cf = CompletableFuture.anyOf(cf1, cf2, cf3);
Object result = cf.join();
System.out.println(result);
System.out.println("耗时:" + sw.getTime(TimeUnit.MILLISECONDS));
四、练习
@Test
public void test1() {
CompletableFuture<String> cfA = CompletableFuture.supplyAsync(() -> {
try {
TimeUnit.MILLISECONDS.sleep(1000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
return "result A";
});
CompletableFuture<String> cfB = CompletableFuture.supplyAsync(() -> {
try {
TimeUnit.MILLISECONDS.sleep(2000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
return "result B";
});
CompletableFuture<String> cfC = cfA.thenCombine(cfB, (a, b) -> {
try {
TimeUnit.MILLISECONDS.sleep(3000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
return a + ":" + b + ":" + "resultC";
});
StopWatch sw = StopWatch.createStarted();
System.out.println(cfC.join());
System.out.println("总耗时: " + sw.getTime(TimeUnit.MILLISECONDS) + "ms");
}
输出结果:
result A:result B:resultC
总耗时: 5011ms
@Test
public void test2() {
CompletableFuture<String> cfA = CompletableFuture.supplyAsync(() -> {
try {
TimeUnit.MILLISECONDS.sleep(1000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
return "result A";
});
CompletableFuture<String> cfB = CompletableFuture.supplyAsync(() -> {
try {
TimeUnit.MILLISECONDS.sleep(1000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
return "result B";
});
CompletableFuture<String> cfC = cfA.applyToEither(cfB, res -> {
try {
TimeUnit.MILLISECONDS.sleep(3000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
return res + ":" + "resultC";
});
StopWatch sw = StopWatch.createStarted();
System.out.println(cfC.join());
System.out.println("总耗时: " + sw.getTime(TimeUnit.MILLISECONDS) + "ms");
}
输出结果:
result A:resultC
总耗时: 4009ms
@Test
public void test3() {
CompletableFuture<String> cfA = CompletableFuture.supplyAsync(() -> {
try {
TimeUnit.MILLISECONDS.sleep(1000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
return "result A";
});
CompletableFuture<String> cfB = CompletableFuture.supplyAsync(() -> {
try {
TimeUnit.MILLISECONDS.sleep(1000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
return "result B";
});
CompletableFuture<String> cfC = CompletableFuture.supplyAsync(() -> {
try {
TimeUnit.MILLISECONDS.sleep(1000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
return "result C";
});
CompletableFuture<String> cfD = CompletableFuture.anyOf(cfA, cfB, cfC).thenApply(res -> {
try {
TimeUnit.MILLISECONDS.sleep(2000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
return res + ":" + "resultD";
});
StopWatch sw = StopWatch.createStarted();
System.out.println(cfD.join());
System.out.println("总耗时: " + sw.getTime(TimeUnit.MILLISECONDS) + "ms");
}
输出结果:
result A:resultD
总耗时: 3009ms
@Test
public void test4() {
CompletableFuture<String> cfA = CompletableFuture.supplyAsync(() -> {
try {
TimeUnit.MILLISECONDS.sleep(1000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
return "result A";
});
CompletableFuture<String> cfB = CompletableFuture.supplyAsync(() -> {
try {
TimeUnit.MILLISECONDS.sleep(2000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
return "result B";
});
CompletableFuture<String> cfC = CompletableFuture.supplyAsync(() -> {
try {
TimeUnit.MILLISECONDS.sleep(3000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
return "result C";
});
CompletableFuture<String> cfD = CompletableFuture.allOf(cfA, cfB, cfC).thenApply(res -> {
try {
TimeUnit.MILLISECONDS.sleep(2000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
String a = cfA.join();
String b = cfB.join();
String c = cfC.join();
return a + ":" + b + ":" + c + ":" + "resultD";
});
StopWatch sw = StopWatch.createStarted();
System.out.println(cfD.join());
System.out.println("总耗时: " + sw.getTime(TimeUnit.MILLISECONDS) + "ms");
}
输出耗时:
result A:result B:result C:resultD
总耗时: 4997ms