day10 异步编排

1.线程池详解

1.线程池的作用

image-20221020231346667

2.线程池的创建方式

  1. newSingleThreadExecutor 创建一个单线程化的线程池,它只会用唯一的工作线程来执行任务,保证所有任务按照指定顺序(FIFO, LIFO, 优先级)执行。
  2. newFixedThreadPool 创建一个定长线程池,可控制线程最大并发数,超出的线程会在队列中等待。
  3. newScheduledThreadPool 创建一个可定期或者延时执行任务的定长线程池,支持定时及周期性任务执行。
  4. newCachedThreadPool 创建一个可缓存线程池,如果线程池长度超过处理需要,可灵活回收空闲线程,若无可回收,则新建线程。

3.线程池7个核心参数

  1. int corePoolSize, 核心线程大小 线程池创建时,就初始化的线程数量

  2. int maximumPoolSize,最大线程大小

  3. long keepAliveTime, 超过corePoolSize的线程多久不活动被销毁时间 就是除核心线程外的线程,过了这段时间还是空闲就销毁

  4. TimeUnit unit,时间单位 上面那参数的单位

  5. BlockingQueue workQueue 任务队列 当任务数超过核心线程数时,多出的那些线程会放在任务队列中等待,若任务队列也满了,那么才创建非核心线程来执行

  6. ThreadFactory threadFactory 线程池工厂 用来生产线程的,下面是默认的线程工场的代码,代码少我才贴的,大致就做了给创建的线程分组,命名,然后优先级都设置成了 5

  7. RejectedExecutionHandler handler 拒绝策略 啥时候要拒绝呢,就是当队列+最大线程数都满足不了任务的执行时,多出来的任务没地放也没地执行的时候,这个时候我们需要舍弃了,是舍弃最开始运行的那几个线程呢,还是后面多出的线程呢,舍弃时抛异常还是不抛异常呢?主要就是如下前四种,默认是第一种Abort,舍弃后面来的多余的任务并抛异常,CallerRun是直接调用这些任务的run方法来执行,我也不抛弃你们,一起执行就完事了,DiscardOldest呢就是抛弃最早执行的那几个,也就是把前浪拍死在沙滩上,Discard呢也是舍弃后面多余的,但是不抛异常.

4.4种线程池创建方式的使用场景

  • newCachedThreadPool:

    • 底层:返回ThreadPoolExecutor实例,corePoolSize为0;maximumPoolSize为Integer.MAX_VALUE;keepAliveTime为60L;时间单位TimeUnit.SECONDS;workQueue为SynchronousQueue(同步队列)
    • 通俗:当有新任务到来,则插入到SynchronousQueue中,由于SynchronousQueue是同步队列,因此会在池中寻找可用线程来执行,若有可以线程则执行,若没有可用线程则创建一个线程来执行该任务;若池中线程空闲时间超过指定时间,则该线程会被销毁。
    • 适用:执行很多短期的异步任务
  • newFixedThreadPool:

    • 底层:返回ThreadPoolExecutor实例,接收参数为所设定线程数量n,corePoolSize和maximumPoolSize均为n;keepAliveTime为0L;时间单位TimeUnit.MILLISECONDS;WorkQueue为:new LinkedBlockingQueue() 无界阻塞队列
    • 通俗:创建可容纳固定数量线程的池子,每个线程的存活时间是无限的,当池子满了就不再添加线程了;如果池中的所有线程均在繁忙状态,对于新任务会进入阻塞队列中(无界的阻塞队列)
    • 适用:执行长期任务
  • newSingleThreadExecutor:

    • 底层:FinalizableDelegatedExecutorService包装的ThreadPoolExecutor实例,corePoolSize为1;maximumPoolSize为1;keepAliveTime为0L;时间单位TimeUnit.MILLISECONDS;workQueue为:new LinkedBlockingQueue() 无解阻塞队列
    • 通俗:创建只有一个线程的线程池,当该线程正繁忙时,对于新任务会进入阻塞队列中(无界的阻塞队列)
    • 适用:按顺序执行任务的场景
  • NewScheduledThreadPool:

    • 底层:创建ScheduledThreadPoolExecutor实例,该对象继承了ThreadPoolExecutor,corePoolSize为传递来的参数,maximumPoolSize为Integer.MAX_VALUE;keepAliveTime为0;时间单位TimeUnit.NANOSECONDS;workQueue为:new DelayedWorkQueue() 一个按超时时间升序排序的队列
    • 通俗:创建一个固定大小的线程池,线程池内线程存活时间无限制,线程池可以支持定时及周期性任务执行,如果所有线程均处于繁忙状态,对于新任务会进入DelayedWorkQueue队列中,这是一种按照超时时间排序的队列结构
    • 适用:执行周期性任务

2.CompletableFuture使用

1.创建异步对象

image-20221020232233824

image-20221020232244036

    public static void main(String[] args) throws ExecutionException, InterruptedException {
        CompletableFuture<Void> voidCompletableFuture = CompletableFuture.runAsync(() -> {
            int n = 10 / 2;
            System.out.println("我没返回值,Thread-" + Thread.currentThread() + "中输出:" + n);
        });
 
        Thread.sleep(100);
 
        CompletableFuture<Integer> integerCompletableFuture = CompletableFuture.supplyAsync(() -> {
            int n = 10 / 2;
            System.out.println("我有返回值,Thread-" + Thread.currentThread() + "中输出:" + n);
            return n;
        });
        System.out.println("我的返回值是:"+integerCompletableFuture.get());
 
    }

image-20221020232315978

2…完成回调与异常的感知

image-20221020232340325

whenComplete是在调用者前面任务执行完后继续执行内容,可以获取前面任务的返回结果与捕获的异常,当然异常了返回结果一般都是null,exceptionally是捕获异常并且回调方法,来返回新的结果

    public static void main(String[] args) throws ExecutionException, InterruptedException {
 
        CompletableFuture<Integer> integerCompletableFuture = CompletableFuture.supplyAsync(() -> {
            int n = 10 / 0;
            System.out.println("我有返回值,Thread-" + Thread.currentThread() + "中输出:" + n);
            return n;
        }).whenCompleteAsync((res,exception)->{
            System.out.println("res:"+res+" exception:"+exception.getMessage());
        }).exceptionally((throwable)->{
            return 0;
        });
        System.out.println("返回结果:"+integerCompletableFuture.get());
    }

3.handle最终处理

image-20221020232417487

// 有异常时    
public static void main(String[] args) throws ExecutionException, InterruptedException {
 
        CompletableFuture<Integer> integerCompletableFuture = CompletableFuture.supplyAsync(() -> {
            int n = 10 / 0;
            System.out.println("我有返回值,Thread-" + Thread.currentThread() + "中输出:" + n);
            return n;
        }).handle((res,exception) ->{
            if(res != null){
                res = res*2;
            }
            if(exception != null){
                res = 0;
            }
            return res;
        });
        System.out.println("返回结果:"+integerCompletableFuture.get());
    }

// 没异常时
    public static void main(String[] args) throws ExecutionException, InterruptedException {
 
        CompletableFuture<Integer> integerCompletableFuture = CompletableFuture.supplyAsync(() -> {
            int n = 10 / 2;
            System.out.println("我有返回值,Thread-" + Thread.currentThread() + "中输出:" + n);
            return n;
        }).handle((res,exception) ->{
            if(res != null){
                res = res*2;
            }
            if(exception != null){
                res = 0;
            }
            return res;
        });
        System.out.println("返回结果:"+integerCompletableFuture.get());
    }

4.线程串行化

image-20221020232712665

5.两任务组合,都要完成

image-20221020232733104

    public static void main(String[] args) throws ExecutionException, InterruptedException {
 
        CompletableFuture<Object> integerCompletableFuture1 = CompletableFuture.supplyAsync(() -> {
            System.out.println("任务一执行中...");
            int n = 10 / 2;
            System.out.println("任务一执行结束");
            return n;
        });
 
        CompletableFuture<Object> integerCompletableFuture2 = CompletableFuture.supplyAsync(() -> {
            System.out.println("任务二执行中...");
            int n = 5 / 2;
            System.out.println("任务二执行结束.");
            return n;
        });
 
        CompletableFuture<String> objectCompletableFuture = integerCompletableFuture1.thenCombine(integerCompletableFuture2, (r1, r2) -> {
            String r3 = "";
            System.out.println("任务三执行中");
            r3 += r3+r1+","+r2;
            System.out.println("任务三执行结束");
            return r3;
        });
 
        System.out.println("任务三返回结果:"+objectCompletableFuture.get());
    }

6.两任务组合,一个完成

image-20221020232827016

image-20221020232836267

image-20221020232846683

image-20221020232856763

7.多任务组合

image-20221020232933599

    public static void main(String[] args) throws ExecutionException, InterruptedException {
 
        CompletableFuture<Object> integerCompletableFuture1 = CompletableFuture.supplyAsync(() -> {
            System.out.println("任务一查询商品图片执行中...");
            System.out.println("任务一执行结束");
            return "huawei121.jpg";
        });
 
        CompletableFuture<Object> integerCompletableFuture2 = CompletableFuture.supplyAsync(() -> {
            System.out.println("任务二查询商品属性执行中...");
            System.out.println("任务二执行结束.");
            return "256G+黑色";
        });
 
        CompletableFuture<Object> integerCompletableFuture3 = CompletableFuture.supplyAsync(() -> {
            System.out.println("任务二查询商品品牌执行中...");
            System.out.println("任务二执行结束.");
            return "华为";
        });
 
        CompletableFuture<Void> completableFuture = CompletableFuture.allOf(integerCompletableFuture1, integerCompletableFuture2, integerCompletableFuture3);
        //此方法会阻塞式等待,直到三个方法都执行完
        completableFuture.get();
        System.out.println("main线程结束...");
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值