【JUC】1.CompletableFuture异步编程
文章目录
- FutureTask简述
- FutureTask缺点
- CompletableFuture
- CompletableFuture的API
- 4.1 CompletableFuture的创建
- 4.2 获得结果和触发计算
- 4.3 对计算结果进行处理
- 4.4 对计算结果进行消费
- 4.5 对计算速度进行选用
- 4.6 对计算结果进行合并
- 4.7 多任务组合
- 4.8 回调方法
- 函数式接口总结
- 5.1 BiConsumer
- 5.2 BiFunction
- 5.3 BiPredication
1. FutureTask简述
FutureTask同时实现了Runable和Future接口
Future是Java5新加的一个接口,它提供了一种异步并行计算的功能
public interface Future
{
boolean cancel(boolean mayInterruptIfRunning);
boolean isDone();
V get() throws InterruptedException, ExecutionException;
V get(long timeout, TimeUnit unit)
throws InterruptedException, ExecutionException, TimeoutException;
}
- 通过是实现Runable接口,就可以完成线程的创建
而FutureTask既然实现了这两个接口,那么肯定会有两个接口所对应的功能
- FutureTask的三个特点:多线程/有返回/异步任务
2. FutureTask缺点
- get()阻塞,非要等到结果才会离开
- isDone()轮询,浪费无谓的CPU资源,也不见得能及时获取到计算结果
3. CompletableFuture
正因为有FutureTask的这些缺点,CompletableFuture才会出现
CompletableFuture能够更好地结果这些问题
- 在Java8中,CompletableFuture提供了非常强大的Future的扩展功能,可以帮助我们简化异步编程的复杂性,并且提供了函数式编程的能力,可以通过回调的方式处理计算结果,也提供了转换和组合CompletableFuture的方法
- 它可能代表一个明确完成的Future,也有可能代表一个完成阶段(CompletionStage),它支持在计算完成以后触发一些函数或执行某些动作
- 它实现了Future和CompletionStage接口
4. CompletableFuture的API
4.1 CompletableFuture的创建
CompletableFuture 提供了四个静态方法来创建一个异步操作
//runAsync方法不支持返回值
public static CompletableFuture<Void> runAsync(Runnable runnable)
public static CompletableFuture<Void> runAsync(Runnable runnable, Executor executor)
//supplyAsync可以支持返回值
public static <U> CompletableFuture<U> supplyAsync(Supplier<U> supplier)
public static <U> CompletableFuture<U> supplyAsync(Supplier<U> supplier, Executor executor)
其中带有Executor参数的方法是可以自己指定线程池的
其中runAsync没有返回值
4.2 获得结果和触发计算
- get:不见不散(会抛出异常),不管计算是否计算完成都会阻塞
- get(long timeout, TimeUnit unit):在规定时间内没有结果,则会跳过
- getNow(T valueIfAbsent):没有计算完成的情况下,给我一个替代结果计算完,返回计算完成后的结果、没算完,返回设定的valuelfAbsent
- join() :和get方法差不多,只是不抛出异常罢了
complete:主动触发计算,是否打算get方法立刻返回括号值
public T get() throws InterruptedException, ExecutionException
public T get(long timeout, TimeUnit unit)
public T getNow(T valueIfAbsent)
public T join()
public boolean complete(T value)
4.3 对计算结果进行处理
- thenApply:计算结果存在依赖关系,两个线程串行化,只要一个线程有异常,就停
handle:有异常也可以往下一步走,可以根据带的异常进行判断
public CompletableFuture thenApply(
Function<? super T,? extends U> fn) {
return uniApplyStage(null, fn);
}
public CompletableFuture handle(
BiFunction<? super T, Throwable, ? extends U> fn) {
return uniHandleStage(null, fn);
}
4.4 对计算结果进行消费
- thenRun:任务A执行完任务B,并且B不需要A的结果
- thenAccept:任务A执行完执行B,B需要A的结果,但是任务B无返回值
thenApply:任务A执行完执行B,B需要A的结果,B有返回
public CompletableFuture
thenRun(Runnable action) public CompletableFuture
thenAccept(Consumer<? super T> action) public CompletableFuture thenApply(
Function<? super T,? extends U> fn) {return uniApplyStage(null, fn);
}
带了Async的方法表示的是:会重新在线程池中启动一个线程来执行任务
4.5 对计算速度进行选用
- applyToEither:谁快就用谁的结果
- applyToEither:两个任务有一个执行完成,获取它的返回值,处理任务并有新的返回值
- acceptEither:两个任务有一个执行完成,获取它的返回值,处理任务,没有新的返回值
runAfterEither:两个任务有一个执行完成,不需要获取 future 的结果,处理任务,也没有返回值
public CompletableFuture applyToEither
public CompletableFuture applyToEitherAsyncpublic CompletableFuture
acceptEither
public CompletableFutureacceptEitherAsync public CompletableFuture
runAfterEither
public CompletableFuturerunAfterEitherAsync
4.6 对计算结果进行合并
- thenCombine:组合两个future,获取两个future的返回结果,并返回当前任务的返回值
- thenAcceptBoth:组合两个future,获取两个future的返回结果,然后处理任务,没有返回值
runAfterBoth:组合两个future,不需要获取future的结果,只需要两个future处理完任务后处理该任务
public CompletableFuture
thenCombine
public CompletableFuturethenAcceptBoth
public CompletableFuturerunAfterBoth
4.7 多任务组合
- allOf:等待所有任务完成
anyOf:只要又一个任务完成
public static CompletableFuture
allOf
public static CompletableFuture
还没有评论,来说两句吧...