异步回顾

线程池(Executors)

在这里插入图片描述

在这里插入图片描述

代码实现:

在这里插入图片描述
Runnable设置线程任务

在这里插入图片描述
在这里插入图片描述


常见的4种线程池


1 Executors.newCacheThreadPool(): 可缓存线程池,先查看池中有没有以前建立的线程,如果有,就直接使用。如果没有,就建一个新的线程加入池中,缓存型池子通常用于执行一些生存期很短的异步型任务。 线程池核心线程大小=0;都可回收

2 Executors.newFixedThreadPool(int n): 创建一个可重用固定个数的线程池,以共享的无界队列方式来运行这些线程。线程池核心线程大小=线程池最大线程数量都不可回收

3 Executors.newScheduledThreadPool(int n): 创建一个定长线程池,支持定时及周期性任务执行。做定时任务的线程池

4 Executors.newSingleThreadExecutor(): 创建一个单线程化的线程池,它只会用唯一的工作线程来执行任务,保证所有任务按照指定顺序(FIFO, LIFO, 优先级)执行。单线程的线程池,后台从队列里面获取任务,挨个执行。


创建线程池

ExecutorService es = Executors.newFixedThreadPool(2);

提交异步任务到线程池


1、Executors.submit(new RunnableImpl()); //有返回值
2、Executors.execute(new RunnableImpl()); //无返回值

原始线程池创建

在这里插入图片描述

线程池的七大参数


一、corePoolSize 线程池核心线程大小

线程池中会维护一个最小的线程数量,即使这些线程处理空闲状态,他们也不会 被销毁,除非设置了allowCoreThreadTimeOut。这里的最小线程数量即是corePoolSize。


二、maximumPoolSize 线程池最大线程数量

一个任务被提交到线程池后,首先会缓存到工作队列(后面会介绍)中,如果工作队列满了,则会创建一个新线程,然后从工作队列中的取出一个任务交由新线程来处理,而将刚提交的任务放入工作队列。线程池不会无限制的去创建新线程,它会有一个最大线程数量的限制,这个数量即由maximunPoolSize来指定。

三、keepAliveTime 空闲线程存活时间

一个线程如果处于空闲状态,并且当前的线程数量大于corePoolSize,那么在指定时间后,这个空闲线程会被销毁,这里的指定时间由keepAliveTime来设定

四、unit 空间线程存活时间单位

keepAliveTime的计量单位

五、workQueue 工作队列

新任务被提交后,会先进入到此工作队列中,任务调度时再从队列中取出任务。jdk中提供了四种工作队列:

①ArrayBlockingQueue

基于数组的有界阻塞队列,按FIFO排序。新任务进来后,会放到该队列的队尾,有界的数组可以防止资源耗尽问题。当线程池中线程数量达到corePoolSize后,再有新任务进来,则会将任务放入该队列的队尾,等待被调度。如果队列已经是满的,则创建一个新线程,如果线程数量已经达到maxPoolSize,则会执行拒绝策略。

②LinkedBlockingQuene

基于链表的无界阻塞队列(其实最大容量为Interger.MAX),按照FIFO排序。由于该队列的近似无界性,当线程池中线程数量达到corePoolSize后,再有新任务进来,会一直存入该队列,而不会去创建新线程直到maxPoolSize,因此使用该工作队列时,参数maxPoolSize其实是不起作用的。

③SynchronousQuene

一个不缓存任务的阻塞队列,生产者放入一个任务必须等到消费者取出这个任务。也就是说新任务进来时,不会缓存,而是直接被调度执行该任务,如果没有可用线程,则创建新线程,如果线程数量达到maxPoolSize,则执行拒绝策略。

④PriorityBlockingQueue

具有优先级的无界阻塞队列,优先级通过参数Comparator实现。

六、threadFactory 线程工厂

创建一个新线程时使用的工厂,可以用来设定线程名、是否为daemon线程等等

七、handler 拒绝策略

当工作队列中的任务已到达最大限制,并且线程池中的线程数量也达到最大限制,这时如果有新任务提交进来,该如何处理呢。这里的拒绝策略,就是解决这个问题的,jdk中提供了4中拒绝策略:

①CallerRunsPolicy

该策略下,在调用者线程中直接执行被拒绝任务的run方法,除非线程池已经shutdown,则直接抛弃任务。

②AbortPolicy

该策略下,直接丢弃任务,并抛出RejectedExecutionException异常

③DiscardPolicy

该策略下,直接丢弃任务,什么都不做。

④DiscardOldestPolicy

该策略下,抛弃进入队列最早的那个任务,然后尝试把这次拒绝的任务放入队列



异步编排


1、创建异步对象 CompletableFuture

在这里插入图片描述
2、异常处理


CompletionStage exceptionally(fn);
CompletionStage whenComplete(consumer);
CompletionStage whenCompleteAsync(consumer);
CompletionStage handle(fn);
CompletionStage handleAsync(fn);
whenComplete() 和 exceptionally() 、handle()系列方法就类似于 try{}finally{}中的 finally{}, 无论是否发生异常都会执行 whenComplete() 中的回调函数 consumer 和 handle() 中的回调函数 fn。

whenComplete() 和 exceptionally()、handle() 的区别在于 whenComplete() 不支持返回结果,而 exceptionally()、handle() 是支持返回结果的。

在这里插入图片描述


在这里插入图片描述

3、线程串行化方法

thenApply、thenAccept、thenRun、thenCompose
public <U> CompletionStage<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 CompletionStage<Void> thenRun(Runnable action);
public CompletionStage<Void> thenRunAsync(Runnable action);
public CompletionStage<Void> thenRunAsync(Runnable 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);

thenApply 系列函数里参数 fn 的类型是接口 Function<T, R>,这个接口里与 CompletionStage 相关的方法是R apply(T t),这个方法既能接收参数也支持返回值,所以 thenApply 系列方法返回的是CompletionStage。

thenAccept 系列方法里参数 consumer 的类型是接口Consumer<>,这个接口里与 CompletionStage 相关的方法是void accept(T t),这个方法虽然支持参数,但却不支持回值,所以 thenAccept 系列方法返回的是CompletionStage Void

thenRun 系列方法里 action 的参数是 Runnable,所以 action 既不能接收参数也不支持返回值,所以 thenRun 系列方法返回的也是CompletionStage 《void》

这些方法里面 Async 代表的是异步执行 fn、consumer 或者 action。其中,需要你注意的是 thenCompose 系列方法,这个系列的方法会新创建出一个子流程,最终结果和 thenApply 系列是相同的。

在这里插入图片描述
在这里插入图片描述


4、描述 AND 汇聚关系

CompletionStage 接口里面描述 OR 汇聚关系,主要是 applyToEither、acceptEither 和 runAfterEither 系列的接口,这些接口的区别也是源自 fn、consumer、action 这三个核心参数不同。

CompletionStage<R> thenCombine(other, fn);
CompletionStage<R> thenCombineAsync(other, fn);
CompletionStage<Void> thenAcceptBoth(other, consumer);
CompletionStage<Void> thenAcceptBothAsync(other, consumer);
CompletionStage<Void> runAfterBoth(other, action);
CompletionStage<Void> runAfterBothAsync(other, action);
CompletionStage applyToEither(other, fn);
CompletionStage applyToEitherAsync(other, fn);
CompletionStage acceptEither(other, consumer);
CompletionStage acceptEitherAsync(other, consumer);
CompletionStage runAfterEither(other, action);
CompletionStage runAfterEitherAsync(other, action);

在这里插入图片描述


runAfterBothAsync(other, action)示例 不能感知前面函数的结果,没有返回值

在这里插入图片描述


thenAcceptBothAsync(other, consumer);示例能感知到前面任务返回的结果,无返回值

在这里插入图片描述


thenCombineAsync(other, fn);示例能感知到前面任务返回的结果,有返回值

在这里插入图片描述
在这里插入图片描述


runAfterEitherAsync(other, action); 两个任务,一个完成就能执行这个方法,不感知结果,自己也没有返回值

在这里插入图片描述

acceptEitherAsync(other, consumer); 两个任务,一个完成就能执行这个方法,能接收上面方法的返回结果,但是也没有返回值。

在这里插入图片描述

applyToEitherAsync(other, fn); 能感知结果,而且有返回值。


在这里插入图片描述


5、多任务组合


allof 顾名思义,就是所有的任务执行完成后返回future


在这里插入图片描述


anyof 就是只要有一个任务执行完成后就返回future将第一个完成的参数带着一起返回

在这里插入图片描述


异步代码示例


//1、sku基本信息的获取 pms_sku_info执行完后,//2、sku图片信息 pms_sku_images 异步执行

//1、sku基本信息的获取 pms_sku_info执行完后, //3、获取spu销售属性组合、 //4、获取spu介绍 pms_spu_info_desc 图片信息介绍、 //5、获取spu规格参数信息 (所有属性值 主体)异步执行

 SkuItemVo skuItemVo = new SkuItemVo();
        //1、Sku基本信息  pms_sku_info

        CompletableFuture<SkuInfoEntity> infofuture = CompletableFuture.supplyAsync(() -> {
            //1、sku基本信息的获取  pms_sku_info
            SkuInfoEntity info = this.getById(skuId);
            skuItemVo.setInfo(info);
            return info;
        }, executor);

        CompletableFuture<Void> saleAttrfuture = infofuture.thenAcceptAsync((res) -> {

            //3、获取spu销售属性组合
            List<SkuItemSaleAttrVo> saleAttrVo = skuSaleAttrValueService.getSaleAttrsBySpuId(res.getSpuId());
            skuItemVo.setSaleAttr(saleAttrVo);

        }, executor);

        CompletableFuture<Void> descfuture = infofuture.thenAcceptAsync((res) -> {
            //4、获取spu介绍 pms_spu_info_desc 图片信息介绍

            SpuInfoDescEntity spuInfo = spuInfoDescService.getById(res.getSpuId());
            skuItemVo.setDesp(spuInfo);

        }, executor);

        CompletableFuture<Void> baseAttrfuture = infofuture.thenAcceptAsync((res) -> {
            //5、获取spu规格参数信息 (所有属性值 主体)

            List<SpuItemAttrGroupVo> attrGroupVos = attrGroupService.getAttrGroupWithAttrsByspuId(res.getSpuId(), res.getCatalogId());

            skuItemVo.setGroupAttrs(attrGroupVos);

        }, executor);


        //2、sku图片信息  pms_sku_images

        CompletableFuture<Void> imagesfuture = CompletableFuture.runAsync(() -> {
            List<SkuImagesEntity> images = imagesService.getImagesBySkuId(skuId);
            skuItemVo.setImages(images);

        }, executor);


        //等待所有任务都完成
         CompletableFuture.allOf(saleAttrfuture,descfuture,baseAttrfuture,imagesfuture).get();


        return skuItemVo;
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值