线程池&异步编排

1 篇文章 0 订阅
1 篇文章 0 订阅

线程池

 1、初始化线程的4种方式
    1.1、集成Thread类
    1.2、实现Runnable接口
    1.3、实现Callable接口+FutureTask(可拿到返回结果,可以处理异常)
    1.4、线程池  可以控制资源,性能稳定
 方式1和方式2:主进程无法获取线程的运算结果。不适合当前场景
 方式3:主进程可以获取线程的运算结果,但是不利于控制服务器中的线程资源。可导致服务器资源耗尽
 方式4:通过如下两种方式初始化线程池

Executors.newFiexedThread(3);
 
 new ThreadPoolExecutor(corePoolSize,
                        maximumPoolSize,
                        keepAliveTime,
                        TimeOut,
                        unit,
                        workQueue,
                        threadFactory,
                        heandler);
通过线程池性能稳定,也可以获取执行结果,并捕获异常。但是,在业务复杂情况下。一个异步调用可能会依赖于另一个异步调用的执行结果
​
2、线程池创建:
    2.1、创建线程池
        3.1.1、七大参数
        
            corePoolSize:核心线程数(一直存在,除非设置了核心线程数超时时间),线程池创建完毕后就准备就绪的线程数量,就等待来接收异步任务去执行,都是就绪状态,只有在提交任务时就会start;
            
            maximumPoolSize:最大线程数量,最多N个线程同时执行任务。
            
            keepAliveTime:存活时间,当空闲线程数量大于核心数量时,超过这个存活时间后,会释放空闲的线程(maximumPoolSize-maximumPoolSize)=被释放的线程。
            
            unit:时间单位。
            
            workQueue:阻塞队列,用于最大线程被占满,来保存没有被执行的任务,只要有空闲的线程,就会去队列里面取出新的任务继续执行。
            
            threadFactory:线程的创建工厂。
            
            heandler:拒绝策略,按照我们指定的策略处理被阻塞的任务。默认使用丢弃策略
                (1)、丢弃最老任务
                (2)、。。。。
                (3)、直接丢弃任务
                (4)、将队头直接丢弃
            
        3.1.2、执行顺序
        
            3.1.2.1、创建好线程池,准备好核心线程,准备接收任务
            
            3.1.2.2、新任务进来,用核心线程执行任务
                (1)核心线程满了以后就会进去阻塞队列,空闲的核心线程就会去队列里面去新的任务
                (2)阻塞队列满了就会去开启新的线程,最多开启线程数位最大线程数。
                (3)如果线程开到最大线程数了,还有任务进来,就会启用我们指定的拒绝策略去处理任务
                (4)所有的线程创建都是有我们的线程工厂进行创建
            
        3.1.3、线程池类型
            灵活线程池:核心线程数为0,最大线程为Integer最大值,在空闲时间都会被回收;
Executors.newCachedThreadPool();
            固定线程池:设置固定线程数,最大线程数和核心线程数一致
            
Executors.newFixedThreadPool(5);
            
            任务调度线程池:用来做定时任务的
            
Executors.newScheduledThreadPool()
            
            单线程池:核心和最大都只有1个线程,队列为无界队列,顺序执行
           
 Executors.newSingleThreadExecutor();

CompletableFuture异步编排

说明:多个异步任务运行时可能会依赖于另一个线程的结果
​
1、runAsync使用方式:没有返回值
    
CompletableFuture<Void> runAsync = CompletableFuture.runAsync(() -> {
            //执行代码
        }, executor);
        
2、supplyAsync使用方式:有返回值
   
 CompletableFuture<Object> supplyAsync = CompletableFuture.supplyAsync(() -> {
            return null;
        }, executor);
        
3、whenComplete、whenCompleteAsync:在 supplyAsync、runAsync执行完毕后还想做其他任务就可以使用链式调用whenComplete(是指当前任务的线程执行继续执行)、whenCompleteAsync(是重新提交到线程池进行执行),这两个可以接收到成功值或者异常信息,只能作为监听成功或失败。

CompletableFuture<Object> supplyAsync = CompletableFuture.supplyAsync(() -> {
            return null;
        }, executor).whenComplete((res,exception)->{
            System.out.println("结果是:"+res+"异常是:"+exception);
        });
        
4、exceptionally:还可以链式调用exceptionally,可以获取到异常信息并且可以修改最终值

CompletableFuture<Object> supplyAsync = CompletableFuture.supplyAsync(() -> {
            return null;
        }, executor).whenComplete((res,exception)->{
            System.out.println("结果是:"+res+"异常是:"+exception);
        }).exceptionally((exception)->{
            return 10;
        });
​
5、handle方法:可以接受两个参数(成功值,异常信息),返回一个参数(可以修改最终返回值),相当于方法执行后的处理
CompletableFuture<Integer> handle = CompletableFuture.supplyAsync(() -> {
            return 20;
        }, executor).handle((res, exception) -> {
            if (res!=null){
                System.out.println("结果是:" + res);
                return res;
            }else{
                System.out.println("异常是:" + exception);
                return 10;
            }
        });
        
6、线程串行化方法
    统一解释:链式调用方法后不加Async(是指当前任务的线程执行继续执行),加上Async(是重新提交到线程池进行执行)
    
    6.1、thenRun、thenRunAsync方法:是要上面的任务执行完毕后才开始执行此方法的后续操作,无返回结果。
    
.thenRunAsync(()->{
            System.out.println("执行后续操作。。。");
        },executor);
        
    6.2、thenAccept、thenAcceptAsync:有一个入参(消费处理结果),接收处理结果进行后续操作,无返回结          果。
    
.thenAcceptAsync((res)->{
            System.out.println("接收到结果:"+res+"执行后续操作。。。");
        },executor);
        
    6.3、thenApply、thenApplyAsync:接收返回结果,并进行后续操作,并返回当前任务的返回值。
    
.thenApplyAsync((res)->{
            System.out.println("接收到结果:"+res+"执行后续操作。。。");
            return 30;
        },executor);
7、两任务组合
    统一解释:链式调用方法后不加Async(是指当前任务的线程执行继续执行),加上Async(是重新提交到线程池进行执行)
    
    7.1、thenCombine、thenCombineAsync:组合两个futre的返回结果,并且返回当前任务的返回值
    
CompletableFuture<Integer> supplyAsync1 = CompletableFuture.supplyAsync(() -> {
            System.out.println("任务1执行完毕!");
            return 10;
        }, executor);
        CompletableFuture<Integer> supplyAsync2 = CompletableFuture.supplyAsync(() -> {
            System.out.println("任务2执行完毕");
            return 20;
        }, executor);
        CompletableFuture<Integer> combineAsync = supplyAsync1.thenCombineAsync(supplyAsync2, (res1, res2) -> {
            System.out.println("结合任务1和任务2的结果计算出任务3,并返回");
            return 30;
        }, executor);
        
    7.2、thenAcceptBoth、thenAcceptBothAsync:组合两个futre,然后处理人物,没有返回值
    
CompletableFuture<Void> acceptBothAsync = supplyAsync1.thenAcceptBothAsync(supplyAsync2, (res1, res2) -> {
            System.out.println("结合任务1和任务2的结果执行任务3,没有返回值!");
        }, executor);
        
    7.3、thenAfterBoth、thenAfterBothAsync:组合两个futre,不需要返回结果,只需要处理两个Future后执行该任务。
    
CompletableFuture<Void> afterBothAsync = supplyAsync1.runAfterBothAsync(supplyAsync2, () -> {
            System.out.println("任务1和任务2执行完执行任务3.没有返回值!");
        }, executor);
        
8、两个任务组合 完成一个
    8.1、applyToEitherAsync、applyToEither
    
supplyAsync1.applyToEitherAsync(supplyAsync2,(res)->{
            System.out.println("只要有一个完成就接收值,处理并返回值!");
            return 3;
        },executor);
        
     8.2、acceptEitherAsync、acceptEither
     
supplyAsync1.acceptEitherAsync(supplyAsync2,(res)->{
            System.out.println("只要有一个完成就接收值,处理不能返回值!");
        },executor);
        
     8.3、runAfterEitherAsync、runAfterEither
     
supplyAsync1.runAfterEitherAsync(supplyAsync2,()->{
            System.out.println("只要有一个完成不接受值,处直接理不能返回值!");
        },executor);
        
9、多任务组合
    9.1、allOf:等待所有任务完成
    
CompletableFuture<Void> all = CompletableFuture.allOf(supplyAsync1, supplyAsync2);
        all.get();
    9.2、anyOf:只要有一个任务完成
   
 CompletableFuture<Object> all = CompletableFuture.anyOf(supplyAsync1, supplyAsync2);
        all.get();//获取的是最快成功的那个数据

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值