异步----CompletableFuture

一、线程回顾

1、初始化线程的4种方式

1. 继承Thread

Thread01 thread = new Thread01();
thread.start(); //启动线程```

2. 实现Runnable接口

Runnable01 runnable01 = new Runnable01();
new Thread(runnable01).start();

3. 实现Callable接口+FutureTask

FutureTask<Integer> futureTask = new FutureTask<>(new Callable01());
new Thread(futureTask).start();//阻塞等待整个线程执行完成,获取返回结果
Integer integer = futureTask.get();


4. 线程池

给线程池直接提交任务。

- 1、创建:
    - 1)、Executors
    - 2)、new ThreadPoolExecutor

区别:1,2不能得到返回值,3可以获取返回值
           1,2,3都不能控制资源
           4可以控制资源,性能稳定

实现方式:

Executors.newFiexedThreadPool(3);

//或者

new ThreadPoolExecutor(corePoolSize, maximumPoolSize, keepAliveTime, TimeUnit unit, workQueue, threadFactory, handler)

通过线程池性能稳定,也可以获取执行结果,并捕获异常,但是。在业务复杂情况下,一个异步调用可能会依赖于另一个异步调用的执行结果。

* * *

2、线程池的七大参数

ThreadPoolExecutor

1. corePoolSize:[5]核心线程数[一直存在];线程池,创建好以后就准备就绪的线程数量,就等待来接受异步任务去执行*     5个 Thread thread = new Thread();
2. maximumPoolSize[200]:最大线程数量;控制资源
3. keepAliveTime:存活时间。如果当前的线程数量大于core数量,释放空闲的线程(maximumPoolSize-corePoolSize)。只要线程空闲大于指定的keepAliveTime;
4. unit:时间单位
5. BlockingQueue<Runnable> workQueue:阻塞队列。如果任务有很多,就会将目前多的任务放在队列里面。只要有线程空闲,就会取队列里取出新的任务继续
6. threadFactory:线程的创建工厂。
7. RejectedExecutionHandler handler:如果队列满了,按照我们指定的拒绝策略拒绝执行任务。

运行流程:

1. 线程池创建,准备好core数量的核心线程,准备接受任务
2. 新的任务进来,用core准备好的空闲线程执行。
    - core满了,就将再进来的任务放入阻塞队列中。空闲的core就会自己去阻塞队列获取任务执行
    - 阻塞队列满了,就直接开线程执行,最大只能开到max指定的数量
    - max都执行好了,Max-core数量空闲的线程会在keepAliveTime指定的时间后自动销毁,最终保持到core大小。
    - 如果线程开到了max的数量,还有新任务进来,就会使用reject指定的拒绝策略进行处理

3. 所有线程创建都是由指定的factory创建的。

面试:
一个线程池 core7;max20 queue:50, 100 并发进来怎么分配的;

先有7个能直接得到执行,接下来50个进入队列排队,在多开13个继续执行。现在70个被安排上了,剩下30个默认拒绝策略。


 3、常见的4种线程池


1. Executors.newCachedThreadPool()  core是0,所有都可回收
2. Executors.newFixedThreadPool() 固定大小,core=max; 都不可回收
3. Executors.newScheduledThreadPool() 定时任务的线程池
4. Executors.newSingleThreadExecutor() 单线程的线程池,后台队列里面获取任务,挨个执行


二、CompletableFuture 异步编排

 1、创建异步对象

CompletableFuture 提供了四个静态方法来创建一个异步操作。

- static CompletableFuture<Void> runAsync (Runnable runnable)
- public static CompletableFuture<Void> runAsync(Runnable runnable, Executor executor)
- public static <U> CompletableFuture<U> supplyAsync(Supplier<U> suppiler)
- public static <U> CompletableFuture<U> supplyAsync(Suppiler<U> suppiler, Executor executor)

1、runXxxx都是没有返回结果的,supplyXxx都是可以获取返回结果的
2、可以传入自定义的线程池,否则就用默认的线程池。
 

CompletableFuture<Void> voidCompletableFuture = CompletableFuture.runAsync(() -> {    System.out.println("当前线程:" + Thread.currentThread().getId());    
int i = 10 / 2;    
System.out.println("运行结果:" + i);}, executorService);


 2、计算完成时回调方法

- public CompletableFuture<T> whenComplete(BiConsumer<? super T, ? super Throwable> action)
- public CompletableFuture<T> whenCompleteAsync(BiConsumer<? super T, ? super Throwable> action)
- public CompletableFuture<T> whenCompleteAsync(BiConsumer<? super T, ? super Throwable> action, Executor executor)
- public CompletableFuture<T> exceptionally(Function<Function<Throwable, ? extends T> fn)

whenComplete可以处理正常和异常的计算结果,exceptionally 处理异常情况。
whenComplete和whenCompleteAsync的区别:

whenComplete:是执行当前任务的线程执行继续执行whenComplete的任务。
whenCompleteAsync:是执行把whenCompleteAsync这个任务继续提交给线程池来进行执行。

方法不以Async结尾,意味着Action使用相同的线程执行,而Async可能会使用其他线程执行(如果是使用相同的线程池,也可能会被同一个线程选中执行)

CompletableFuture<Integer> future = CompletableFuture.supplyAsync(() -> {    System.out.println("当前线程:" + Thread.currentThread().getId());    
    int i = 10 / 0;    System.out.println("运行结果:" + i);
    return i;}, executorService).whenComplete((res,exc)->{
    System.out.println("异步任务成功完成了...结果是:" + res + ";异常是:" + exc);}).exceptionally(throwable -> {    return 10;});

3、handle方法

- public <U> completionStage<U> handle(BiConsumer<? super T, Throwable, ? extends U> fn)
- public <U> completionStage<U> handleAsync(BiConsumer<? super T, Throwable, ? extends U> fn)
- public <U> completionStage<U> handleAsync(BiConsumer<? super T, Throwable, ? extends U> fn, Executor executor)

CompletableFuture<Integer> future = CompletableFuture.supplyAsync(() -> {    System.out.println("当前线程:" + Thread.currentThread().getId());
    int i = 10 / 0;    System.out.println("运行结果:" + i);
    return i;}, executorService).handle((res,thr)->{
    if(res != null){
        return res * 2;
    }    
    if(thr != null){
        return 0;
    }
    return 0;});

4、线程串行化方法

- public <U> CompletableFuture<U> thenApply(Function<? super T, ? extends U> fn)

- public <U> CompletableFuture<U> thenApplyAsync(Function<? super T, ? extends U> fn)

- public <U> CompletableFuture<U> thenApplyAsync(Function<? super T, ? extends U> fn, Executor executor)

- public <U> completionStage<U> thenAccept(Consumer<? super T> action)

- public <U> completionStage<U> thenAcceptAsync(Consumer<? super T> action)

- public <U> completionStage<U> thenAcceptAsync(Consumer<? super T> action, Executor executor)

thenApply方法:当一个线程依赖另一个线程时,获取上一个任务返回的结果,并返回当前任务的返回值

thenAcctpt方法:消费处理结果。接收任务的处理结果,并消费处理,无返回结果。

thenRun方法:只要上面的任务执行完成,就开始执行thenRun, 只是处理完任务后,执行thenRun的后续操作

thenRun 的后续操作
带有Async默认是异步执行的。同之前。


 

CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> {    System.out.println("当前线程:" + Thread.currentThread().getId());
    int i = 10 / 4;
    System.out.println("运行结果:" + i);
    return i;}, executorService).thenApplyAsync(res -> {
    System.out.println("任务2启动了" + res);
    return "Hello" + res;}, executorService);

 5、两任务组合-都要完成

- public <U,V> CompletableFuture<V> thenCombine(CompletionStage<? extends U> other, BiFunction<? super T, ? super U, ? extends V> fn)

- public <U,V> CompletableFuture<V> thenCombineAsync(CompletionStage<? extends U> other, BiFunction<? super T, ? super U, ? extends V> fn)

- public <U,V> CompletableFuture<V> thenCombineAsync(CompletionStage<? extends U> other, BiFunction<? super T, ? super U, ? extends V> fn, Executor executor)

- public <U> CompletableFuture<Void> thenAcceptBoth(CompletionStage<? extends U> other, BiFunction<? super T, ? super U  action)

- public <U> CompletableFuture<Void> thenAcceptBothAsync(CompletionStage<? extends U> other, BiFunction<? super T, ? super U> action)

- public <U> CompletableFuture<Void> thenAcceptBothAsync(CompletionStage<? extends U> other, BiFunction<? super T, ? super U> action, Executor executor)

- public CompletableFuture<Void> runAfterBoth(CompletionStage<?> other, Runnable action)

- public CompletableFuture<Void> runAfterBothAsync(CompletionStage<?> other, Runnable action)

两个任务必须都完成,触发该任务

CompletableFuture<Integer> future01 =CompletableFuture.supplyAsync(() -> {
            System.out.println("任务1线程:" + Thread.currentThread().getId()); 
            int i = 10 / 4;                            
            System.out.println("任务1结束:");
            return i;
        }, executorService);
        CompletableFuture<String> future02 = CompletableFuture.supplyAsync(() -> {            System.out.println("任务2线程:" + Thread.currentThread().getId());            System.out.println("任务2结束");
            return "Hello";
        }, executorService);
//        future01.runAfterBothAsync(future02,()->{
//            System.out.println("任务3开始");
//        },executorService);
//        future01.thenAcceptBothAsync(future02, (f1,f2)->{
//            System.out.println("任务3开始,之前的结果" + f1 + "-->" + f2);
//        },executorService);
        CompletableFuture<String> future = future01.thenCombineAsync(future02, (f1, f2) -> {            
return f1 + ":" + f2 + "->haha";
        }, executorService);

 6、两任务组合-一个完成

- public CompletionStage<Void> runAfterEitherAsync    (CompletionStage<?> other,     Runnable action,     Executor executor);

- public CompletionStage<Void> runAfterEitherAsync    (CompletionStage<?> other,     Runnable action);

- public CompletionStage<Void> runAfterEither(CompletionStage<?> other, Runnable action);


- public CompletionStage<Void> acceptEitherAsync    (CompletionStage<? extends T> other,     Consumer<? super T> action,     Executor executor);

- public CompletionStage<Void> acceptEitherAsync    (CompletionStage<? extends T> other,     Consumer<? super T> action);

- public CompletionStage<Void> acceptEither    (CompletionStage<? extends T> other,     Consumer<? super T> action);

- 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> applyToEither    (CompletionStage<? extends T> other,     Function<? super T, U> fn);

7、多任务组合

- public static CompletableFuture<Void> allOf(CompletableFuture<?>... cfs)

- public static CompletableFuture<Object> anyOf(CompletableFuture<?>... 
cfs)

allof:等待所有任务完成
anyof:只要有一个任务完成

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值