异步调用
Future
一般不使用Future
Future 也是一个异步计算结果返回接口,目的获取返回值结果。但是 future 在获取返回值结构的时候,方法必须同步阻塞等待返回值结果。
Get : 获取结果(等待,阻塞)
Get(timeout) : 获取结果,指定等待时间
Cancel : 取消当前任务
isDone : 判断任务是否已经完成 (轮询)
futrure 对于结果获取不是很方便,只能通过同步阻塞的方式获取结果,或者是轮询的方式获取到结果;阻塞的方式获取返回值结果与异步的思想想违背,轮询方式又很占用 cpu 资源,也不能及时得到我们结果。
CompletableFuture
即异步编排
CompletableFuture
可以帮助我们简化异步编程复杂性,提供了函数式编程的能力,可以通过回调函数的方式处理计算结果。
public class CompletableFuture<T> implements Future<T>, CompletionStage<T>
CompletableFuture 具有Future 的特性,还实现了CompletionStage 接口,具备CompletionStage
接口的特性: 串行执行,并行执行,聚合(AND 聚合,OR 聚合)
1.串行关系执行
then – 然后,也就是表示下一步,所以通常是一个串行的关系体现,then后面的单词(比如 run/apply/accept)就是函数是接口中抽象方法名称;
利用上一步的执行结果,去进行下一步任务执行,任务执行具有先后顺序,因此把这种操作叫做串行关系
public CompletionStage<Void> thenRun(Runnable action);
public CompletionStage<Void> thenRunAsync(Runnable action);
public CompletableFuture<Void> thenRunAsync(Runnable action,Executor executor);
public <U> CompletableFuture<U> thenApply( Function<? super T,? extends U> fn) ;
public <U> CompletionStage<U> thenApplyAsync(Function<? super T,? extends U> fn);
public <U> CompletionStage<U> thenApplyAsync(Function<? super T,? extends U> fn,Executor executor);
public CompletionStage<Void> thenAccept(Consumer<? super T> action);
public CompletionStage<Void> thenAcceptAsync(Consumer<? super T> action);
public CompletionStage<Void> thenAcceptAsync(Consumer<? super T> action, Executor executor);
public <U> CompletionStage<U> thenCompose(Function<? super T, ? extends CompletionStage<U>> fn);
public <U> CompletionStage<U> thenComposeAsync(Function<? super T, ? extends CompletionStage<U>> fn);
public <U> CompletionStage<U> thenComposeAsync(Function<? super T, ? extends CompletionStage<U>> fn, Executor executor);
2.聚合and
Combine…… with …… 和 both…… and …… 都是要求两者都必须满足,也就是and 且的关系。
public <U,V> CompletionStage<V> thenCombine (CompletionStage<? extends U> other, BiFunction<? super T,? super U,? extends V> fn);
public <U,V> CompletionStage<V> thenCombineAsync (CompletionStage<? extends U> other, BiFunction<? super T,? super U,? extends V> fn);
public <U,V> CompletionStage<V> thenCombineAsync (CompletionStage<? extends U> other, BiFunction<? super T,? super U,? extends V> fn, Executor executor);
public <U> CompletionStage<Void> thenAcceptBoth (CompletionStage<? extends U> other, BiConsumer<? super T, ? super U> action);
public <U> CompletionStage<Void> thenAcceptBothAsync (CompletionStage<? extends U> other, BiConsumer<? super T, ? super U> action);
public <U> CompletionStage<Void> thenAcceptBothAsync(CompletionStage<? extends U> other, BiConsumer<? super T, ? super U> action, Executor executor);
public CompletionStage<Void> runAfterBoth(CompletionStage<?> other, Runnable action);
public CompletionStage<Void> runAfterBothAsync(CompletionStage<?> other, Runnable action);
public CompletionStage<Void> runAfterBothAsync(CompletionStage<?> other, Runnable action, Executor executor);
3.聚合or
public <U> CompletionStage<U> applyToEitherAsync (CompletionStage<? extends T> other, Function<? super T, U> fn);
public <U> CompletionStage<U> applyToEitherAsync (CompletionStage<? extends T> other, Function<? super T, U> fn, Executor executor);
public <U> CompletionStage<U> applyToEitherAsync (CompletionStage<? extends T> other, Function<? super T, U> fn);
public <U> CompletionStage<U> applyToEitherAsync (CompletionStage<? extends T> other, Function<? super T, U> fn, Executor executor);
public CompletionStage<Void> acceptEither (CompletionStage<? extends T> other, Consumer<? super T> action);
public CompletionStage<Void> acceptEitherAsync (CompletionStage<? extends T> other, Consumer<? super T> action);
public CompletionStage<Void> acceptEitherAsync (CompletionStage<? extends T> other, Consumer<? super T> action, Executor executor);
public CompletionStage<Void> runAfterEither(CompletionStage<?> other, Runnable action);
public CompletionStage<Void> runAfterEitherAsync (CompletionStage<?> other, Runnable action);
public CompletionStage<Void> runAfterEitherAsync (CompletionStage<?> other, Runnable action, Executor executor);
4.异常处理
public CompletionStage<T> exceptionally(Function<Throwable, ? extends T> fn);
public CompletionStage<T> whenComplete (BiConsumer<? super T, ? super Throwable> action);
public CompletionStage<T> whenCompleteAsync (BiConsumer<? super T, ? super Throwable> action);
public CompletionStage<T> whenCompleteAsync (BiConsumer<? super T, ? super Throwable> action, Executor executor);
public <U> CompletionStage<U> handle (BiFunction<? super T, Throwable, ? extends U> fn);
public <U> CompletionStage<U> handleAsync (BiFunction<? super T, Throwable, ? extends U> fn);
public <U> CompletionStage<U> handleAsync (BiFunction<? super T, Throwable, ? extends U> fn, Executor executor);
异步开启
异步开启
CompletableFuture 提供了 4 个静态的方法,来创建一个异步操作(异步开启: 从这 4 个静态的方法开发即可)
1.runAsync方法:
没有返回值的方法,不关注返回值
public static CompletableFuture<Void> runAsync(Runnable runnable);
public static CompletableFuture<Void> runAsync(Runnable runnable,Executor executor);
2.supplyAsync :
有返回值,关注返回值的。
public static <U> CompletableFuture<U> supplyAsync(Supplier<U> supplier);
public static <U> CompletableFuture<U> supplyAsync(Supplier<U> supplier,Executor executor)
案例:
方法说明
1.runAsync 没有返回值
2.1 public static CompletableFuture<Void> runAsync(Runnable runnable); 使用默认的线程池
2.2 public static CompletableFuture<Void> runAsync(Runnable runnable, Executor executor) 自定义线程池
<p>
2.supplyAsync: 有返回值的,关注返回值
2.1 public static <U> CompletableFuture<U> supplyAsync(Supplier<U> supplier) 使用默认的线程池
2.3 public static <U> CompletableFuture<U> supplyAsync(Supplier<U> supplier, Executor executor) 自定义线程池
<p>
3. thenRun 第一步执行完执行第二步,第二步的不关心第一执行的结果
3.1 public static <U> CompletableFuture<U> supplyAsync(Supplier<U> supplier)
3.2 public CompletableFuture<Void> thenRun(Runnable action) 不关心返回值,也不关心也行结果,只有顺序,1执行后2才会执行
<p>
4. thenApply 有返回值U,也关心上一步的返回值,上一步的返回值会被当成参数,参数类型为T,也是顺序执行,1执行后执行2
4.1 public static <U> CompletableFuture<U> supplyAsync(Supplier<U> supplier)
4.2 public <U> CompletableFuture<U> thenApply(Function<? super T,? extends U> fn);
<p>
5. thenAccept 没有返回结果,关心上一步的执行结果,上一步的执行结果会被当成参数,参数 T
5.1 public static <U> CompletableFuture<U> supplyAsync(Supplier<U> supplier)
5.2 public CompletableFuture<Void> thenAccept(Consumer<? super T> action)
<p>
6. thenCompose 有返回值,顺序执行,第一步的返回结果为thenCompose的参数,允许对2个CompletionStage流水线进行操作,第一个操作完成时,将第一个的结果作为第二个参数
public <U> CompletableFuture<U> thenCompose(Function<? super T, ? extends CompletionStage<U>> fn)
<p>
7.thenCombine
7.1 聚合and,有返回值 当
7.2 把两个任务都执行完毕后,会将两个结果都交给thenCombine去处理
7.3 thenAcceptBoth(没有返回值)与 thenCombine(有返回值)的区别
public <U,V> CompletableFuture<V> thenCombine( CompletionStage<? extends U> other, BiFunction<? super T,? super U,? extends V> fn)
<p>
8.thenAcceptBoth
8.1 聚合and
8.2 没有返回值 会把两个任务都执行完毕后,回将两个结果都交给thenAcceptBoth去处理
public <U> CompletableFuture<Void> thenAcceptBoth( CompletionStage<? extends U> other, BiConsumer<? super T, ? super U> action)
<p>
9.runAfterBoth
9.1 聚合and
9.2没有返回值,
9.3当有连个任务时,两个任务都执行完,在执行下一个任务
public CompletableFuture<Void> runAfterBoth(CompletionStage<?> other,Runnable action);
<p>
10. applyToEither
10.1 聚合 or
10.2 有返回值
10.2 针对2个CompletionStage,将计算速度最快的那个CompletionStage的结果作为下一步的处理
public <U> CompletableFuture<U> applyToEither(CompletionStage<? extends T> other, Function<? super T, U> fn);
<p>
11.exceptionally
11.1 异常处理
11.2 有返回值
简单理解 就是当程序执行错误进入exceptionally方法
public CompletableFuture<T> exceptionally( Function<Throwable, ? extends T> fn)
<p>
12.whenComplete
可以获取到上一次的返回结果
public CompletableFuture<T> whenComplete(BiConsumer<? super T, ? super Throwable> action)
<p>
13. handle
有返回值
相当于 try()finally() ,可以对执行结果进行处理,也可以对异常信息进行处理
public <U> CompletableFuture<U> handle( BiFunction<? super T, Throwable, ? extends U> fn)
runAsync
1.public static CompletableFuture runAsync(Runnable runnable);
public static void main(String[] args) throws ExecutionException, InterruptedException {
log.info("主线程start……");
/**
* 异步任务
* 没有返回值,为定义线程池
* public static CompletableFuture<Void> runAsync(Runnable runnable);
*/
CompletableFuture<Void> runAsync = CompletableFuture.runAsync(
() -> {
log.info("子线程future线程start……");
int i = 10 / 2;
log.info("线程名称:{},线程执行结果:{}", Thread.currentThread().getName(), i);
log.info("子线程future线程end……");
});
// 调用异步任务
runAsync.get();
log.info("主线程end……");
}
2.public static CompletableFuture runAsync(Runnable runnable, Executor executor)
public static void main(String[] args) throws ExecutionException, InterruptedException {
AsyFutureDemo.runAsync();
}
/**
* 线程池对象
*/
public static ThreadPoolExecutor threadPool = new ThreadPoolExecutor(Runtime.getRuntime().availableProcessors(),
Runtime.getRuntime().availableProcessors() + 1,
3,
TimeUnit.SECONDS,
new LinkedBlockingQueue<Runnable>(3),
Executors.defaultThreadFactory(),
new ThreadPoolExecutor.CallerRunsPolicy());
public static void runAsync() throws ExecutionException, InterruptedException {
log.info("主线程start……");
/**
* 异步任务
* 没有返回值,为定义线程池
* public static CompletableFuture<Void> runAsync(Runnable runnable);
*/
CompletableFuture<Void> runAsync = CompletableFuture.runAsync(
() -> {
log.info("子线程future线程start……");
int i = 10 / 2;
log.info("线程名称:{},线程执行结果:{}", Thread.currentThread().getName(), i);
log.info("子线程future线程end……");
}, threadPool);
// 调用异步任务
runAsync.get();
log.info("主线程end……");
}
supplyAsync
public static CompletableFuture supplyAsync(Supplier supplier)
public static void supplyAsync() throws ExecutionException, InterruptedException {
log.info("主线程start……");
CompletableFuture<Integer> supplyAsync = CompletableFuture.supplyAsync(
() -> {
log.info("子线程future线程start……");
int i = 10 / 2;
log.info("线程名称:{},线程执行结果:{}", Thread.currentThread().getName(), i);
log.info("子线程future线程end……");
return i;
});
supplyAsync.get();
log.info("主线程end……");
}
public static CompletableFuture supplyAsync(Supplier supplier, Executor executor)
public static void supplyAsync() throws ExecutionException, InterruptedException {
log.info("主线程start……");
CompletableFuture<Integer> supplyAsync = CompletableFuture.supplyAsync(
() -> {
log.info("子线程future线程start……");
int i = 10 / 2;
log.info("线程名称:{},线程执行结果:{}", Thread.currentThread().getName(), i);
log.info("子线程future线程end……");
return i;
},threadPool);
supplyAsync.get();
log.info("主线程end……");
}
/**
* 线程池对象
*/
public static ThreadPoolExecutor threadPool = new ThreadPoolExecutor(Runtime.getRuntime().availableProcessors(),
Runtime.getRuntime().availableProcessors() + 1,
3,
TimeUnit.SECONDS,
new LinkedBlockingQueue<Runnable>(3),
Executors.defaultThreadFactory(),
new ThreadPoolExecutor.CallerRunsPolicy());
thenRun
/**
* 第一步执行完执行第二步,第二步的不关心第一执行的结果
* <p>
* 5. thenRun
* 5.1 public static <U> CompletableFuture<U> supplyAsync(Supplier<U> supplier)
* 5.2 public CompletableFuture<Void> thenRun(Runnable action) 不关心返回值,也不关心也行结果,只有顺序,1执行后
*/
public static void main(String[] args) throws Exception {
// 1.public static <U> CompletableFuture<U> supplyAsync(Supplier<U> supplier)
// 2.public CompletableFuture<Void> thenRun(Runnable action) 不关心返回值,也不关心也行结果,只有顺序,1执行后2才会执行
CompletableFuture<Void> thenRun = CompletableFuture.supplyAsync(
() -> {
int i = 10 / 2;
log.info("线程名称:{},线程执行结果:{}", Thread.currentThread().getName(), i);
return i;
}
).thenRun(
() -> {
log.info("上一步执行结束这一步才会执行,且不关心返回值,也不关心也行结果,只有顺序");
}
);
// 异步调用执行
thenRun.get();
}
thenApply
/**
* 第一步执行完执行第二步,第二步的参数就是第一步返回的结果
* <p>
* 6. thenApply 有返回值U,也关心上一步的返回值,上一步的返回值会被当成参数,参数类型为T,也是顺序执行,1执行后执行2
* 6.1 public static <U> CompletableFuture<U> supplyAsync(Supplier<U> supplier)
* 6.2 public <U> CompletableFuture<U> thenApply(Function<? super T,? extends U> fn);
*/
public static void main(String[] args) throws Exception {
// thenApply 有返回值U,也关心上一步的返回值,上一步的返回值会被当成参数,参数类型为T,也是顺序执行,1执行后执行2
// 1.public static <U> CompletableFuture<U> supplyAsync(Supplier<U> supplier)
// 2.public <U> CompletableFuture<U> thenApply(Function<? super T,? extends U> fn);
CompletableFuture<Integer> thenApply = CompletableFuture.supplyAsync(
() -> {
int i = 10 / 2;
log.info("线程名称:{},线程执行结果:{}", Thread.currentThread().getName(), i);
return i;
}
).thenApply((e) -> {
return e + 2;
});
Integer e = thenApply.get();
System.out.println("e = " + e);
}
thenAccept
/**
*第一不执行完执行第二步,没有返回值,第一步的返回值为第二步的参数
* supplyAsync
* 1 public static <U> CompletableFuture<U> supplyAsync(Supplier<U> supplier)
* 2 public CompletableFuture<Void> thenAccept(Consumer<? super T> action)
*/
public static void main(String[] args) throws Exception {
// thenAccept 没有返回结果,关心上一步的执行结果,上一步的执行结果会被当成参数,参数 T
// 1.public static <U> CompletableFuture<U> supplyAsync(Supplier<U> supplier)
// 2.public CompletableFuture<Void> thenAccept(Consumer<? super T> action)
CompletableFuture<Void> thenAccept = CompletableFuture.supplyAsync(
() -> {
int i = 10 / 2;
log.info("线程名称:{},线程执行结果:{}", Thread.currentThread().getName(), i);
return i;
}
).thenAccept(
e -> {
int k = e + 3;
log.info("k的结果为{}", k);
}
);
// 调用异步方法
thenAccept.get();
}
thenCompose
/**
* 1. 有返回值
* 2. 顺序执行,第一步的返回结果为thenCompose的参数
* 3. 允许对2个CompletionStage流水线进行操作,第一个操作完成时,将第一个的结果作为第二个参数
* thenCompose
* public <U> CompletableFuture<U> thenCompose(Function<? super T, ? extends CompletionStage<U>> fn)
*/
public static void main(String[] args) throws Exception {
// thenCompose
// public <U> CompletableFuture<U> thenCompose(Function<? super T, ? extends CompletionStage<U>> fn)
// 第一次执行
CompletableFuture<Integer> thenCompose = CompletableFuture.supplyAsync(
() -> {
int i = 10 / 2;
log.info("线程名称:{},线程执行结果:{}", Thread.currentThread().getName(), i);
return i;
}).thenCompose(new Function<Integer, CompletionStage<Integer>>() {
@Override
public CompletionStage<Integer> apply(Integer i) {
// 第二次执行
CompletableFuture<Integer> supplyAsync = CompletableFuture.supplyAsync(
() -> {
int j = i + 2;
log.info("线程名称:{},线程执行结果:{}", Thread.currentThread().getName(), j);
return j;
});
return supplyAsync;
}
});
// 调用异步
Integer integer = thenCompose.get();
System.out.println("integer = " + integer);
}
thenCombine(and聚合)
/**
* 1. 聚合and
* 2. 有返回值 会把两个任务都执行完毕后,回将两个结果都交给thenCombine去处理
* 3. thenAcceptBoth(没有返回值)与 thenCombine(有返回值)的区别
* <p>
* thenCombine
* public static <U> CompletableFuture<U> supplyAsync(Supplier<U> supplier)
* public <U,V> CompletableFuture<V> thenCombine( CompletionStage<? extends U> other, BiFunction<? super T,? super U,? extends V> fn)
*/
public static void main(String[] args) throws ExecutionException, InterruptedException {
// 聚合and
// 有返回值 会把两个任务都执行完毕后,回将两个结果都交给thenCombine去处理
// public static <U> CompletableFuture<U> supplyAsync(Supplier<U> supplier)
// public <U,V> CompletableFuture<V> thenCombine( CompletionStage<? extends U> other, BiFunction<? super T,? super U,? extends V> fn)
// 第一个执行
CompletableFuture<Integer> f1 = CompletableFuture.supplyAsync(() -> {
int i = 10 / 2;
return i;
});
// 第二个执行
CompletableFuture<Integer> f2 = CompletableFuture.supplyAsync(() -> {
int i = 10 / 3;
return i;
});
// thenCombine 合并操作
CompletableFuture<Integer> thenCombine = f1.thenCombine(f2, (x, y) -> {
log.info("x为第一个执行结果:{}", x);
log.info("y为第二个执行结果:{}", y);
return x + y;
});
// 调用异步方法
Integer integer = thenCombine.get();
System.out.println("最终结果 = " + integer);
}
thenAcceptBoth(and聚合)
/**
* 1. 聚合and
* 2. 没有返回值 会把两个任务都执行完毕后,回将两个结果都交给thenAcceptBoth去处理
* 3. thenAcceptBoth(没有返回值)与 thenCombine(有返回值)的区别
* thenAcceptBoth
* public <U> CompletableFuture<Void> thenAcceptBoth( CompletionStage<? extends U> other, BiConsumer<? super T, ? super U> action);
*/
public static void main(String[] args) throws Exception {
// public <U> CompletableFuture<Void> thenAcceptBoth( CompletionStage<? extends U> other, BiConsumer<? super T, ? super U> action)
// 第一个执行
CompletableFuture<Integer> f1 = CompletableFuture.supplyAsync(() -> {
int i = 10 / 2;
return i;
});
// 第二个执行
CompletableFuture<Integer> f2 = CompletableFuture.supplyAsync(() -> {
int i = 10 / 3;
return i;
});
// thenAcceptBoth 合并操作 ,没有返回值
CompletableFuture<Void> acceptBoth = f1.thenAcceptBoth(f2, (x, y) -> {
log.info("x为第一个执行结果:{}", x);
log.info("y为第二个执行结果:{}", y);
});
// 调用异步方法
acceptBoth.get();
}
runAfterBoth(and聚合)
/**
* 9.runAfterBoth
* 9.1 聚合and
* 9.2没有返回值,
* 9.3当有连个任务时,两个任务都执行完,在执行下一个任务
* public CompletableFuture<Void> runAfterBoth(CompletionStage<?> other,Runnable action);
*/
public static void main(String[] args) throws ExecutionException, InterruptedException {
// public CompletableFuture<Void> runAfterBoth(CompletionStage<?> other,Runnable action);
// 第一个执行
CompletableFuture<Integer> f1 = CompletableFuture.supplyAsync(() -> {
int i = 10 / 2;
return i;
});
// 第二个执行
CompletableFuture<Integer> f2 = CompletableFuture.supplyAsync(() -> {
int i = 10 / 3;
return i;
});
// thenAcceptBoth 合并操作 ,没有返回值
CompletableFuture<Void> afterBoth = f1.runAfterBoth(f2, () -> {
log.info("第一个和第二个执行完,接下来的业务");
});
// 调用异步方法
afterBoth.get();
}
applyToEither(or聚合)
/**
* 10. applyToEither
* 10.1 聚合 or
* 10.2 有返回值
* 10.2 针对2个CompletionStage,将计算速度最快的那个CompletionStage的结果作为下一步的处理
* public <U> CompletableFuture<U> applyToEither(CompletionStage<? extends T> other, Function<? super T, U> fn);
*/
public static void main(String[] args) throws ExecutionException, InterruptedException {
// public <U> CompletableFuture<U> applyToEither(CompletionStage<? extends T> other, Function<? super T, U> fn);
// 第一个执行
CompletableFuture<Integer> f1 = CompletableFuture.supplyAsync(() -> {
int i = 10 / 5;
log.info("第一个执行结果{}",i);
return i;
});
// 第二个执行
CompletableFuture<Integer> f2 = CompletableFuture.supplyAsync(() -> {
int i = 10 / 2;
log.info("第二个执行结果{}",i);
return i;
});
// 将计算速度最快的那个CompletionStage的结果进行处理
CompletableFuture<Integer> applyToEither = f1.applyToEither(f2, res -> {
int i = res + 5;
return i;
});
Integer integer = applyToEither.get();
System.out.println("integer = " + integer);
}
exceptionally(异常处理)
/**
* 11.exceptionally
* 11.1 异常处理
* 11.2 有返回值
* 简单理解 就是当程序执行错误进入exceptionally方法
* public CompletableFuture<T> exceptionally( Function<Throwable, ? extends T> fn)
*
* @param args
*/
public static void main(String[] args) throws ExecutionException, InterruptedException {
CompletableFuture<Integer> exceptionally = CompletableFuture.supplyAsync(() -> {
int i = 10 / 0;
return i;
}).exceptionally(e -> {
log.info("当执行抛出异常进入此方法,异常信息:{}", e.getMessage());
return null;
});
Integer integer = exceptionally.get();
System.out.println("integer = " + integer);
}
whenComplete(异常处理)
/**
* 11.whenComplete
* 可以获取到上一次的返回结果
* public CompletableFuture<T> whenComplete(BiConsumer<? super T, ? super Throwable> action)
*/
public static void main(String[] args) throws ExecutionException, InterruptedException {
//
CompletableFuture<Integer> whenComplete = CompletableFuture.supplyAsync(() -> {
int i = 10 / 5;
return i;
}).whenComplete((t, e) -> {
log.info("上一步的执行结果{}", t);
if (t > 0) {
System.out.println("t 大于 0,结果为: " + t);
}
});
Integer integer = whenComplete.get();
System.out.println("integer = " + integer);
}
handle(异常处理)
/**
* 13. handle
* 有返回值
* 相当于 try()finally() ,可以对执行结果进行处理,也可以对异常信息进行处理
* public <U> CompletableFuture<U> handle( BiFunction<? super T, Throwable, ? extends U> fn)
*/
public static void main(String[] args) throws ExecutionException, InterruptedException {
//
CompletableFuture<Integer> handle = CompletableFuture.supplyAsync(() -> {
int i = 10 / 0;
return i;
}).handle((t, e) -> {
log.info("上一步的执行结果{}", t);
int res = 0;
if (e != null) {
log.info("异常信息{}", e.getMessage());
return null;
}
if (t != null) {
res = t + 1;
}
return res;
});
Integer integer = handle.get();
System.out.println("integer = " + integer);
}
所有代码
import lombok.extern.slf4j.Slf4j;
import org.apache.tomcat.jni.User;
import java.util.concurrent.*;
import java.util.function.Function;
/**
* 异步编排
*/
@Slf4j
public class AsyFutureDemo {
/**
* 1.runAsync 没有返回值
* 2.1 public static CompletableFuture<Void> runAsync(Runnable runnable); 使用默认的线程池
* 2.2 public static CompletableFuture<Void> runAsync(Runnable runnable, Executor executor) 自定义线程池
* <p>
* 2.supplyAsync: 有返回值的,关注返回值
* 2.1 public static <U> CompletableFuture<U> supplyAsync(Supplier<U> supplier) 使用默认的线程池
* 2.3 public static <U> CompletableFuture<U> supplyAsync(Supplier<U> supplier, Executor executor) 自定义线程池
* <p>
* 3. thenRun 第一步执行完执行第二步,第二步的不关心第一执行的结果
* 3.1 public static <U> CompletableFuture<U> supplyAsync(Supplier<U> supplier)
* 3.2 public CompletableFuture<Void> thenRun(Runnable action) 不关心返回值,也不关心也行结果,只有顺序,1执行后2才会执行
* <p>
* 4. thenApply 有返回值U,也关心上一步的返回值,上一步的返回值会被当成参数,参数类型为T,也是顺序执行,1执行后执行2
* 4.1 public static <U> CompletableFuture<U> supplyAsync(Supplier<U> supplier)
* 4.2 public <U> CompletableFuture<U> thenApply(Function<? super T,? extends U> fn);
* <p>
* 5. thenAccept 没有返回结果,关心上一步的执行结果,上一步的执行结果会被当成参数,参数 T
* 5.1 public static <U> CompletableFuture<U> supplyAsync(Supplier<U> supplier)
* 5.2 public CompletableFuture<Void> thenAccept(Consumer<? super T> action)
* <p>
* 6. thenCompose 有返回值,顺序执行,第一步的返回结果为thenCompose的参数,允许对2个CompletionStage流水线进行操作,第一个操作完成时,将第一个的结果作为第二个参数
* public <U> CompletableFuture<U> thenCompose(Function<? super T, ? extends CompletionStage<U>> fn)
* <p>
* 7.thenCombine
* 7.1 聚合and,有返回值 当
* 7.2 把两个任务都执行完毕后,会将两个结果都交给thenCombine去处理
* 7.3 thenAcceptBoth(没有返回值)与 thenCombine(有返回值)的区别
* public <U,V> CompletableFuture<V> thenCombine( CompletionStage<? extends U> other, BiFunction<? super T,? super U,? extends V> fn)
* <p>
* 8.thenAcceptBoth
* 8.1 聚合and
* 8.2 没有返回值 会把两个任务都执行完毕后,回将两个结果都交给thenAcceptBoth去处理
* public <U> CompletableFuture<Void> thenAcceptBoth( CompletionStage<? extends U> other, BiConsumer<? super T, ? super U> action)
* <p>
* 9.runAfterBoth
* 9.1 聚合and
* 9.2没有返回值,
* 9.3当有连个任务时,两个任务都执行完,在执行下一个任务
* public CompletableFuture<Void> runAfterBoth(CompletionStage<?> other,Runnable action);
* <p>
* 10. applyToEither
* 10.1 聚合 or
* 10.2 有返回值
* 10.2 针对2个CompletionStage,将计算速度最快的那个CompletionStage的结果作为下一步的处理
* public <U> CompletableFuture<U> applyToEither(CompletionStage<? extends T> other, Function<? super T, U> fn);
* <p>
* 11.exceptionally
* 11.1 异常处理
* 11.2 有返回值
* 简单理解 就是当程序执行错误进入exceptionally方法
* public CompletableFuture<T> exceptionally( Function<Throwable, ? extends T> fn)
* <p>
* 12.whenComplete
* 可以获取到上一次的返回结果
* public CompletableFuture<T> whenComplete(BiConsumer<? super T, ? super Throwable> action)
* <p>
* 13. handle
* 有返回值
* 相当于 try()finally() ,可以对执行结果进行处理,也可以对异常信息进行处理
* public <U> CompletableFuture<U> handle( BiFunction<? super T, Throwable, ? extends U> fn)
*/
/**
* 13. handle
* 有返回值
* 相当于 try()finally() ,可以对执行结果进行处理,也可以对异常信息进行处理
* public <U> CompletableFuture<U> handle( BiFunction<? super T, Throwable, ? extends U> fn)
*/
public static void main(String[] args) throws ExecutionException, InterruptedException {
//
CompletableFuture<Integer> handle = CompletableFuture.supplyAsync(() -> {
int i = 10 / 0;
return i;
}).handle((t, e) -> {
log.info("上一步的执行结果{}", t);
int res = 0;
if (e != null) {
log.info("异常信息{}", e.getMessage());
return null;
}
if (t != null) {
res = t + 1;
}
return res;
});
Integer integer = handle.get();
System.out.println("integer = " + integer);
}
/**
* 12.whenComplete
* 可以获取到上一次的返回结果
* public CompletableFuture<T> whenComplete(BiConsumer<? super T, ? super Throwable> action)
*/
public static void whenComplete() throws ExecutionException, InterruptedException {
//
CompletableFuture<Integer> whenComplete = CompletableFuture.supplyAsync(() -> {
int i = 10 / 5;
return i;
}).whenComplete((t, e) -> {
log.info("上一步的执行结果{}", t);
if (t > 0) {
System.out.println("t 大于 0,结果为: " + t);
}
});
Integer integer = whenComplete.get();
System.out.println("integer = " + integer);
}
/**
* 11.exceptionally
* 11.1 异常处理
* 11.2 有返回值
* 简单理解 就是当程序执行错误进入exceptionally方法
* public CompletableFuture<T> exceptionally( Function<Throwable, ? extends T> fn)
*/
public static void exceptionally() throws ExecutionException, InterruptedException {
CompletableFuture<Integer> exceptionally = CompletableFuture.supplyAsync(() -> {
int i = 10 / 0;
return i;
}).exceptionally(e -> {
log.info("当执行抛出异常进入此方法,异常信息:{}", e.getMessage());
return null;
});
Integer integer = exceptionally.get();
System.out.println("integer = " + integer);
}
/**
* 10. applyToEither
* 10.1 聚合 or
* 10.2 有返回值
* 10.2 针对2个CompletionStage,将计算速度最快的那个CompletionStage的结果作为下一步的处理
* public <U> CompletableFuture<U> applyToEither(CompletionStage<? extends T> other, Function<? super T, U> fn);
*/
public static void applyToEither() throws ExecutionException, InterruptedException {
// public <U> CompletableFuture<U> applyToEither(CompletionStage<? extends T> other, Function<? super T, U> fn);
// 第一个执行
CompletableFuture<Integer> f1 = CompletableFuture.supplyAsync(() -> {
int i = 10 / 5;
log.info("第一个执行结果{}", i);
return i;
});
// 第二个执行
CompletableFuture<Integer> f2 = CompletableFuture.supplyAsync(() -> {
int i = 10 / 2;
log.info("第二个执行结果{}", i);
return i;
});
// 将计算速度最快的那个CompletionStage的结果进行处理
CompletableFuture<Integer> applyToEither = f1.applyToEither(f2, res -> {
int i = res + 5;
return i;
});
Integer integer = applyToEither.get();
System.out.println("integer = " + integer);
}
/**
* 9.runAfterBoth
* 9.1 聚合and
* 9.2没有返回值,
* 9.3当有连个任务时,两个任务都执行完,在执行下一个任务
* public CompletableFuture<Void> runAfterBoth(CompletionStage<?> other,Runnable action);
*/
public static void runAfterBoth() throws ExecutionException, InterruptedException {
// public CompletableFuture<Void> runAfterBoth(CompletionStage<?> other,Runnable action);
// 第一个执行
CompletableFuture<Integer> f1 = CompletableFuture.supplyAsync(() -> {
int i = 10 / 2;
return i;
});
// 第二个执行
CompletableFuture<Integer> f2 = CompletableFuture.supplyAsync(() -> {
int i = 10 / 3;
return i;
});
// thenAcceptBoth 合并操作 ,没有返回值
CompletableFuture<Void> afterBoth = f1.runAfterBoth(f2, () -> {
log.info("第一个和第二个执行完,接下来的业务");
});
// 调用异步方法
afterBoth.get();
}
/**
* 1. 聚合and
* 2. 没有返回值 会把两个任务都执行完毕后,回将两个结果都交给thenAcceptBoth去处理
* 3. thenAcceptBoth(没有返回值)与 thenCombine(有返回值)的区别
* thenAcceptBoth
* public <U> CompletableFuture<Void> thenAcceptBoth( CompletionStage<? extends U> other, BiConsumer<? super T, ? super U> action);
*/
public static void thenAcceptBoth() throws Exception {
// public <U> CompletableFuture<Void> thenAcceptBoth( CompletionStage<? extends U> other, BiConsumer<? super T, ? super U> action)
// 第一个执行
CompletableFuture<Integer> f1 = CompletableFuture.supplyAsync(() -> {
int i = 10 / 2;
return i;
});
// 第二个执行
CompletableFuture<Integer> f2 = CompletableFuture.supplyAsync(() -> {
int i = 10 / 3;
return i;
});
// thenAcceptBoth 合并操作 ,没有返回值
CompletableFuture<Void> acceptBoth = f1.thenAcceptBoth(f2, (x, y) -> {
log.info("x为第一个执行结果:{}", x);
log.info("y为第二个执行结果:{}", y);
});
// 调用异步方法
acceptBoth.get();
}
/**
* 1. 聚合and
* 2. 有返回值 会把两个任务都执行完毕后,回将两个结果都交给thenCombine去处理
* 3. thenAcceptBoth(没有返回值)与 thenCombine(有返回值)的区别
* <p>
* thenCombine
* public static <U> CompletableFuture<U> supplyAsync(Supplier<U> supplier)
* public <U,V> CompletableFuture<V> thenCombine( CompletionStage<? extends U> other, BiFunction<? super T,? super U,? extends V> fn)
*/
public static void thenCombine() throws ExecutionException, InterruptedException {
// 聚合and
// 有返回值 会把两个任务都执行完毕后,回将两个结果都交给thenCombine去处理
// public static <U> CompletableFuture<U> supplyAsync(Supplier<U> supplier)
// public <U,V> CompletableFuture<V> thenCombine( CompletionStage<? extends U> other, BiFunction<? super T,? super U,? extends V> fn)
// 第一个执行
CompletableFuture<Integer> f1 = CompletableFuture.supplyAsync(() -> {
int i = 10 / 2;
return i;
});
// 第二个执行
CompletableFuture<Integer> f2 = CompletableFuture.supplyAsync(() -> {
int i = 10 / 3;
return i;
});
// thenCombine 合并操作
CompletableFuture<Integer> thenCombine = f1.thenCombine(f2, (x, y) -> {
log.info("x为第一个执行结果:{}", x);
log.info("y为第二个执行结果:{}", y);
return x + y;
});
// 调用异步方法
Integer integer = thenCombine.get();
System.out.println("最终结果 = " + integer);
}
/**
* 1. 有返回值
* 2. 顺序执行,第一步的返回结果为thenCompose的参数
* 3. 允许对2个CompletionStage流水线进行操作,第一个操作完成时,将第一个的结果作为第二个参数
* thenCompose
* public <U> CompletableFuture<U> thenCompose(Function<? super T, ? extends CompletionStage<U>> fn)
*/
public static void thenCompose(String[] args) throws Exception {
// thenCompose
// public <U> CompletableFuture<U> thenCompose(Function<? super T, ? extends CompletionStage<U>> fn)
// 第一次执行
CompletableFuture<Integer> thenCompose = CompletableFuture.supplyAsync(
() -> {
int i = 10 / 2;
log.info("线程名称:{},线程执行结果:{}", Thread.currentThread().getName(), i);
return i;
}).thenCompose(new Function<Integer, CompletionStage<Integer>>() {
@Override
public CompletionStage<Integer> apply(Integer i) {
// 第二次执行
CompletableFuture<Integer> supplyAsync = CompletableFuture.supplyAsync(
() -> {
int j = i + 2;
log.info("线程名称:{},线程执行结果:{}", Thread.currentThread().getName(), j);
return j;
});
return supplyAsync;
}
});
// 调用异步
Integer integer = thenCompose.get();
System.out.println("integer = " + integer);
}
/**
* 第一不执行完执行第二步,没有返回值,第一步的返回值为第二步的参数
* 7. supplyAsync
* 7.1 public static <U> CompletableFuture<U> supplyAsync(Supplier<U> supplier)
* 7.2 public CompletableFuture<Void> thenAccept(Consumer<? super T> action)
*/
public static void thenAccept(String[] args) throws Exception {
// thenAccept 没有返回结果,关心上一步的执行结果,上一步的执行结果会被当成参数,参数 T
// 1.public static <U> CompletableFuture<U> supplyAsync(Supplier<U> supplier)
// 2.public CompletableFuture<Void> thenAccept(Consumer<? super T> action)
CompletableFuture<Void> thenAccept = CompletableFuture.supplyAsync(
() -> {
int i = 10 / 2;
log.info("线程名称:{},线程执行结果:{}", Thread.currentThread().getName(), i);
return i;
}
).thenAccept(
e -> {
int k = e + 3;
log.info("k的结果为{}", k);
}
);
// 调用异步方法
thenAccept.get();
}
/**
* 第一步执行完执行第二步,第二步的参数就是第一步返回的结果
* <p>
* 6. thenApply 有返回值U,也关心上一步的返回值,上一步的返回值会被当成参数,参数类型为T,也是顺序执行,1执行后执行2
* 6.1 public static <U> CompletableFuture<U> supplyAsync(Supplier<U> supplier)
* 6.2 public <U> CompletableFuture<U> thenApply(Function<? super T,? extends U> fn);
*/
public static void thenApply() throws Exception {
// thenApply 有返回值U,也关心上一步的返回值,上一步的返回值会被当成参数,参数类型为T,也是顺序执行,1执行后执行2
// 1.public static <U> CompletableFuture<U> supplyAsync(Supplier<U> supplier)
// 2.public <U> CompletableFuture<U> thenApply(Function<? super T,? extends U> fn);
CompletableFuture<Integer> thenApply = CompletableFuture.supplyAsync(
() -> {
int i = 10 / 2;
log.info("线程名称:{},线程执行结果:{}", Thread.currentThread().getName(), i);
return i;
}
).thenApply((e) -> {
return e + 2;
});
Integer e = thenApply.get();
System.out.println("e = " + e);
}
/**
* 第一步执行完执行第二步,第二步的不关心第一执行的结果
* <p>
* 5. thenRun
* 5.1 public static <U> CompletableFuture<U> supplyAsync(Supplier<U> supplier)
* 5.2 public CompletableFuture<Void> thenRun(Runnable action) 不关心返回值,也不关心也行结果,只有顺序,1执行后2才会执行
*/
public static void thenRun() throws Exception {
// 1.public static <U> CompletableFuture<U> supplyAsync(Supplier<U> supplier)
// 2.public CompletableFuture<Void> thenRun(Runnable action) 不关心返回值,也不关心也行结果,只有顺序,1执行后2才会执行
CompletableFuture<Void> thenRun = CompletableFuture.supplyAsync(
() -> {
int i = 10 / 2;
log.info("线程名称:{},线程执行结果:{}", Thread.currentThread().getName(), i);
return i;
}
).thenRun(
() -> {
log.info("上一步执行结束这一步才会执行,且不关心返回值,也不关心也行结果,只有顺序");
}
);
// 异步调用执行
thenRun.get();
}
/**
* public static <U> CompletableFuture<U> supplyAsync(Supplier<U> supplier) 使用默认的线程池
* public static <U> CompletableFuture<U> supplyAsync(Supplier<U> supplier, Executor executor) 自定义线程池
*/
public static void supplyAsync() throws ExecutionException, InterruptedException {
log.info("主线程start……");
CompletableFuture<Integer> supplyAsync = CompletableFuture.supplyAsync(
() -> {
log.info("子线程future线程start……");
int i = 10 / 2;
log.info("线程名称:{},线程执行结果:{}", Thread.currentThread().getName(), i);
log.info("子线程future线程end……");
return i;
}, threadPool);
supplyAsync.get();
log.info("主线程end……");
}
/**
* 线程池对象
*/
public static ThreadPoolExecutor threadPool = new ThreadPoolExecutor(Runtime.getRuntime().availableProcessors(),
Runtime.getRuntime().availableProcessors() + 1,
3,
TimeUnit.SECONDS,
new LinkedBlockingQueue<Runnable>(3),
Executors.defaultThreadFactory(),
new ThreadPoolExecutor.CallerRunsPolicy());
/**
* 1.public static CompletableFuture<Void> runAsync(Runnable runnable); 使用默认的线程池
* 只需将 ,threadPool 去掉即可
* 2.public static CompletableFuture<Void> runAsync(Runnable runnable, Executor executor) 自定义线程池
* 只需将 ,threadPool 加上即可
*/
public static void runAsync() throws ExecutionException, InterruptedException {
log.info("主线程start……");
/**
* 异步任务
* 没有返回值,为定义线程池
* public static CompletableFuture<Void> runAsync(Runnable runnable);
*/
CompletableFuture<Void> runAsync = CompletableFuture.runAsync(
() -> {
log.info("子线程future线程start……");
int i = 10 / 2;
log.info("线程名称:{},线程执行结果:{}", Thread.currentThread().getName(), i);
log.info("子线程future线程end……");
}, threadPool);
// 调用异步任务
runAsync.get();
log.info("主线程end……");
}
/**
* supplyAsync
*/
/**
* 异步调用
* 异步调用实现一个不需要被等等的方法的返回值,让调用者继续执行(异步执行);
* 在java 中,简单的讲就是开启另一个线程完成程序计算,使得调用者继续执行,不需要等等计算的结果,但是调用者任然需要获取线程的计算结果(不需要同步阻塞等待)。
* 通俗理解就是:
* 主线程将任务交个子线程,主线程就返回,不需要等待执行结果,主线程可以继续往下执行
*/
/**
* Future 也是一个异步计算结果返回接口,目的获取返回值结果。但是 future 在获取返回值结构的时候,方法必须同步阻塞等待返回值结果。
* Get : 获取结果(等待,阻塞)
* Get(timeout) : 获取结果,指定等待时间
* Cancel : 取消当前任务
* isDone : 判断任务是否已经完成 (轮询)
* futrure 对于结果获取不是很方便,只能通过同步阻塞的方式获取结果,或者是轮询的方式获取到结果;阻塞的方式获取返回值结果与异步的思想想违背,轮询方式又很占用 cpu 资源,也不能及时得到我们结果。
*/
/**
* CompletableFuture
* 可以帮助我们简化异步编程复杂性,提供了函数式编程的能力,可以通过回调函数的方式处理计算结果。
* public class CompletableFuture<T> implements Future<T>, CompletionStage<T>
* CompletableFuture 具有Future 的特性,还实现了CompletionStage 接口,具备CompletionStage
* 接口的特性: 串行执行,并行执行,聚合(AND 聚合,OR 聚合)
* 1.串行关系执行
* then – 然后,也就是表示下一步,所以通常是一个串行的关系体现,then后面的单词(比如 run/apply/accept)就是函数是接口中抽象方法名称;
* 利用上一步的执行结果,去进行下一步任务执行,任务执行具有先后顺序,因此把这种操作叫做串行关系
*
* public CompletionStage<Void> thenRun(Runnable action);
* public CompletionStage<Void> thenRunAsync(Runnable action);
* public CompletableFuture<Void> thenRunAsync(Runnable action,Executor executor);
*
* public <U> CompletableFuture<U> thenApply( Function<? super T,? extends U> fn) ;
* public <U> CompletionStage<U> thenApplyAsync(Function<? super T,? extends U> fn);
* public <U> CompletionStage<U> thenApplyAsync(Function<? super T,? extends U> fn,Executor executor);
*
* public CompletionStage<Void> thenAccept(Consumer<? super T> action);
* public CompletionStage<Void> thenAcceptAsync(Consumer<? super T> action);
* public CompletionStage<Void> thenAcceptAsync(Consumer<? super T> action, Executor executor);
*
* public <U> CompletionStage<U> thenCompose(Function<? super T, ? extends CompletionStage<U>> fn);
* public <U> CompletionStage<U> thenComposeAsync(Function<? super T, ? extends CompletionStage<U>> fn);
* public <U> CompletionStage<U> thenComposeAsync(Function<? super T, ? extends CompletionStage<U>> fn, Executor executor);
*
* 2.聚合and
* Combine…… with …… 和 both…… and …… 都是要求两者都必须满足,也就是and 且的关系。
*
* public <U,V> CompletionStage<V> thenCombine (CompletionStage<? extends U> other, BiFunction<? super T,? super U,? extends V> fn);
* public <U,V> CompletionStage<V> thenCombineAsync (CompletionStage<? extends U> other, BiFunction<? super T,? super U,? extends V> fn);
* public <U,V> CompletionStage<V> thenCombineAsync (CompletionStage<? extends U> other, BiFunction<? super T,? super U,? extends V> fn, Executor executor);
*
* public <U> CompletionStage<Void> thenAcceptBoth (CompletionStage<? extends U> other, BiConsumer<? super T, ? super U> action);
* public <U> CompletionStage<Void> thenAcceptBothAsync (CompletionStage<? extends U> other, BiConsumer<? super T, ? super U> action);
* public <U> CompletionStage<Void> thenAcceptBothAsync(CompletionStage<? extends U> other, BiConsumer<? super T, ? super U> action, Executor executor);
*
* public CompletionStage<Void> runAfterBoth(CompletionStage<?> other, Runnable action);
* public CompletionStage<Void> runAfterBothAsync(CompletionStage<?> other, Runnable action);
* public CompletionStage<Void> runAfterBothAsync(CompletionStage<?> other, Runnable action, Executor executor);
*
* 3.聚合or
* public <U> CompletionStage<U> applyToEitherAsync (CompletionStage<? extends T> other, Function<? super T, U> fn);
* public <U> CompletionStage<U> applyToEitherAsync (CompletionStage<? extends T> other, Function<? super T, U> fn, Executor executor);
*
* public <U> CompletionStage<U> applyToEitherAsync (CompletionStage<? extends T> other, Function<? super T, U> fn);
* public <U> CompletionStage<U> applyToEitherAsync (CompletionStage<? extends T> other, Function<? super T, U> fn, Executor executor);
* public CompletionStage<Void> acceptEither (CompletionStage<? extends T> other, Consumer<? super T> action);
*
* public CompletionStage<Void> acceptEitherAsync (CompletionStage<? extends T> other, Consumer<? super T> action);
* public CompletionStage<Void> acceptEitherAsync (CompletionStage<? extends T> other, Consumer<? super T> action, Executor executor);
* public CompletionStage<Void> runAfterEither(CompletionStage<?> other, Runnable action);
* public CompletionStage<Void> runAfterEitherAsync (CompletionStage<?> other, Runnable action);
* public CompletionStage<Void> runAfterEitherAsync (CompletionStage<?> other, Runnable action, Executor executor);
*
* 4.异常处理
* public CompletionStage<T> exceptionally(Function<Throwable, ? extends T> fn);
* public CompletionStage<T> whenComplete (BiConsumer<? super T, ? super Throwable> action);
* public CompletionStage<T> whenCompleteAsync (BiConsumer<? super T, ? super Throwable> action);
* public CompletionStage<T> whenCompleteAsync (BiConsumer<? super T, ? super Throwable> action, Executor executor);
* public <U> CompletionStage<U> handle (BiFunction<? super T, Throwable, ? extends U> fn);
* public <U> CompletionStage<U> handleAsync (BiFunction<? super T, Throwable, ? extends U> fn);
* public <U> CompletionStage<U> handleAsync (BiFunction<? super T, Throwable, ? extends U> fn, Executor executor);
*
*/
/**
* 异步开启
* CompletableFuture 提供了 4 个静态的方法,来创建一个异步操作(异步开启: 从这 4 个静态的方法开发即可)
* 1.runAsync方法:
* 没有返回值的方法,不关注返回值
* public static CompletableFuture<Void> runAsync(Runnable runnable);
* public static CompletableFuture<Void> runAsync(Runnable runnable,Executor executor);
* 2.supplyAsync :
* 有返回值,关注返回值的。
* public static <U> CompletableFuture<U> supplyAsync(Supplier<U> supplier);
* public static <U> CompletableFuture<U> supplyAsync(Supplier<U> supplier,Executor executor)
*/
}
网上找的参考Demo
@Autowired
private ThreadPoolExecutor executor;
// 新建一个包装类对象
SkuItemVo itemVo = new SkuItemVo();
// 开启异步编排实现,提升服务性能 supplyAsync 有返回值
// 1、根据 skuId 查询 sku 基本信息
CompletableFuture<SkuInfoEntity> infoFuture =
CompletableFuture.supplyAsync(() -> {
SkuInfoEntity skuInfoEntity = this.getById(skuId);
itemVo.setInfo(skuInfoEntity);
return skuInfoEntity;
}, executor);
// 2、根据 skuId 查询 sku 图片信息(多个图片),skuId 是外键 runAsync 没有返回值
CompletableFuture<Void> imagesFuture =
CompletableFuture.runAsync(() -> {
List<SkuImagesEntity> imageList =
skuImagesService.list(new
QueryWrapper<SkuImagesEntity>().eq("sku_id", skuId));
itemVo.setImages(imageList);
}, executor);
//3、根据 spuID 获取 spu 的销售属性 (thenAcceptAsync 串行,没有返回值)
CompletableFuture<Void> salesFuture =
infoFuture.thenAcceptAsync((res) -> {
// 获取 sku 与之对应的 spuId
Long spuId = res.getSpuId();
List<SkuItemSaleAttrVo> saleAttrVos =
skuSaleAttrValueService.getSaleAttrs(spuId);
if (saleAttrVos.size() > 0 && saleAttrVos != null) {
itemVo.setAttrSales(saleAttrVos);
}
}, executor);
//4、根据 spuId 查询 spu 的描述信息 (thenAcceptAsync 串行,没有返回值)
CompletableFuture<Void> descFuture =
infoFuture.thenAcceptAsync((res) -> {
// 获取 sku 与之对应的 spuId
Long spuId = res.getSpuId();
SpuInfoDescEntity spuInfoDescEntity =
spuInfoDescService.getOne(new QueryWrapper<SpuInfoDescEntity>()
.eq("spu_id", spuId));
if (spuInfoDescEntity != null) {
itemVo.setDesc(spuInfoDescEntity);
}
}, executor);
//5、根据 spuID,categoryId 查询 sku 分组规格参数属性值 (thenAcceptAsync 串行,没有返回值)
CompletableFuture<Void> groupFuture =
infoFuture.thenAcceptAsync((res) -> {
// 获取 sku 与之对应的 spuId
Long spuId = res.getSpuId();
// 获取分类 id
Long categoryId = res.getCategoryId();
List<SpuAttrGroupVo> attrGroupVos =
attrGroupService.getGroupAttr(spuId, categoryId);
if (attrGroupVos.size() > 0) {
itemVo.setAttrGroups(attrGroupVos);
}
}, executor);
// 等待所有的任务完成后,才能返回结果
try{
CompletableFuture.allOf(infoFuture, imagesFuture, salesFuture, descFuture, groupFuture).get();
catch (Exception e) {
e.printStackTrace();
}