Java - CompletableFuture的作用(经验分享)
·
使用背景:
在实际的项目开发中,当你遇到一个大文件需要批量入库的时候,比如:文件有用户信息,商品信息,商家信息,你需要从这个文件里分批读出来分别存储,然后将这些存储到不同的数据库上。
传统做法:
我们一般是串行执行,例如:先读取用户信息、商品信息、商家信息,然后将这些信息分配存储到分别的表内
我们设想一下,如果数据量非常大,那么这个导入时间是巨大的,我们自然而然的就想到的并行执行,而这个就用到了CompletableFuture
CompletableFuture的作用:
提供了函数式编程和异步执行任务
这里介绍我常用的方法:
创建异步任务:
CompletableFuture.runAsync(...)://没有返回结果
CompletableFuture.supplyAsync(...)://有返回结果
public static CompletableFuture<Void> runAsync(Runnable runnable,
Executor executor) {
return asyncRunStage(screenExecutor(executor), runnable);
}
任务回调方法:
.whenComplete(...)://无论异步任务是正常完成,还是抛出异常,都会执行这个回调;
public CompletableFuture<T> whenComplete(
BiConsumer<? super T, ? super Throwable> action) {
return uniWhenCompleteStage(null, action);
}
这里着重介绍一下runAsync()方法
static CompletableFuture<Void> runAsync(Runnable runnable);
static CompletableFuture<Void> runAsync(Runnable runnable, Executor executor);
第一个方法使用的是默认线程池,其线程数默认等于CPU核心数,当文件数量远大于核心数时,任务会排队等待,无法充分利用IO资源
第二个是使用自定义线程池,可以自定义核心线程数量和最大线程池数量
在使用背景的情况下,是为IO密集型场景(设置线程数为CPU核心数的2-4倍),提升并行处理效率。所以通常选择第二个创建方法。
更多推荐




所有评论(0)