博主名取自《小羊肖恩》中的小羊肖恩,名字为:肖恩,音译为Sean,自己取的姓:阿奇,为符合我们的阅读习惯,连起来组成为ArchieSean。博主志在将博客打造成为个人线上的技术栈,方便自己也方便他人。如博客中有任何错误,请各位指出,谢谢大家
异步&线程池
基础
初始化线程的4种方式
- 继承Thread
- 实现runnable接口
- 实现callable接口+FutureTask
- 线程池
1、2 主进程无法获取线程的运算结果。
3 可以获取线程的运算结果,但是不利于控制服务器中的线程资源。
4 通过下边两种方式初始化线程池:
//第一种
ExecutorService service=Executors.newFixedThreadPool(10);
service.execute(new Runable01());
//第二种
/**
* 第一个参数: corePoolSize: 核心线程数
* 第二个参数: maximumPoolSize: 最大线程数量
* 第三个参数: keepAliveTime : 存活时间 (用于释放多余[maximumPoolSize-corePoolSize]的当前线程)
* 第四个参数: unit : 时间单位
* 第五个参数: workQueue: 阻塞队列。如果任务有很多,就会将目前多的任务放在队列当中,只要有空闲线程,就会依次执行。
* 第六个参数: threadFactory: 线程的创建工厂。
* 第七个参数: handler: 如果队列满了,按照指定的拒绝策略拒绝执行任务。
* ------工作顺序: 准备好核心线程,准备接收任务---> 满了,进入阻塞队列-->队列满了,开新线程--->达到最大线程数,使用拒绝策略,拒绝任务
*/
ThreadPoolExecutor executors=new ThreadPoolExecutor();
##为什么要使用线程池?
CompletableFuture异步编排
创建异步对象
- CompletableFuture提供了四个静态方法来创建一个异步操作:
//1
public static CompletableFuture<Void> runAsync(Runnable runnable) ;
//2
public static CompletableFuture<Void> runAsync(Runnable runnable,
Executor executor);
//3
public static <U> CompletableFuture<U> supplyAsync(Supplier<U> supplier);
//4
public static <U> CompletableFuture<U> supplyAsync(Supplier<U> supplier,
Executor executor);
- runXxxx 都是没有法案会结果的,supplyXxxx都是可以获得返回结果的。
- 可以传入自定义的线程池,否则就用默认的线程池。
计算完成时回调方法
//1
public CompletableFuture<T> whenComplete(
BiConsumer<? super T, ? super Throwable> action)
//2
public CompletableFuture<T> whenCompleteAsync(
BiConsumer<? super T, ? super Throwable> action);
//3
public CompletableFuture<T> whenCompleteAsync(
BiConsumer<? super T, ? super Throwable> action, Executor executor)
//4
public CompletableFuture<T> exceptionally(
Function<Throwable, ? extends T> fn);
- whenComplete可以处理正常和异常的计算结果,exceptionally处理异常情况。
- whenComplete和whenCompleteAsync的区别:
whenComplete: 是执行当前任务的线程继续执行whenComplete的任务。[同步执行]
whenCompleteAsync: 是执行whenCompleteAsync这个任务提交给线程池来进行执行。[异步执行]
handle方法
//1
public <U> CompletableFuture<U> handle(
BiFunction<? super T, Throwable, ? extends U> fn);
//2
public <U> CompletableFuture<U> handleAsync(
BiFunction<? super T, Throwable, ? extends U> fn);
//3.
public <U> CompletableFuture<U> handleAsync(
BiFunction<? super T, Throwable, ? extends U> fn, Executor executor);
线程串行方法
- thenApply方法: 当一个线程依赖另一个线程时,获取上一个任务返回的结果,并返回当前任务的返回值。能接收到上一步的结果,有返回值
- thenAccept方法。消费处理结果。接收任务的处理结果,并消费处理,无返回结果。能接收上一步的结果,但是无返回值
- thenRun方法: 只要上边的任务执行完成,就开始执行thenRun,只是处理完任务后,执行thenRun的后续操作。不能获取一步的执行结果
带有Async默认是异步执行的。
两个任务组合[都完成]
- thenCombine: 组合两个future,获取两个future的返回结果,并返回当前任务的返回值。
- thenAcceptBoth:组合两个future,获取两个future任务的返回结果,然后处理任务,没有返回值。
- runAfterBoth: 组合两个future,不需要获取future的结果,只需两个future处理完任务后,处理该任务。
两个任务组合[单任务完成]
- applyToEither: 两个任务有一个执行完成,获取它的返回值,处理任务并有新的返回值。
- acceptEither: 两个任务有一个执行完成,获取它的返回值,处理任务没有返回值。
多任务组合
- allof:组合多个任务,有返回值。常使用get方法阻塞获取结果。
- anyof: 只要有一个执行成功就返回。
- anyof: 所有任务执行完成后返回future。
|