Future和CompletableFuture

关系: CompletableFuture是Future的一个实现类,它继承了Future接口,并在此基础上提供了更多的功能。CompletableFuture可以看作是对Future的增强和扩展,使得异步编程更加方便和灵活。

  • Future
    • 常用函数
      • get():该函数用于获取异步操作的结果。如果异步操作还未完成,调用该函数会阻塞当前线程,直到异步操作完成并返回结果。
      • wait():该函数用于等待异步操作的完成。如果异步操作还未完成,调用该函数会阻塞当前线程,直到异步操作完成。
      • valid():该函数用于判断 Future 对象是否与一个有效的异步操作关联。如果 Future 对象与一个有效的异步操作关联,则返回 true;否则返回 false。
      • then():该函数用于在 Future 对象完成后执行一个回调函数。回调函数可以是一个可调用对象(如函数、lambda 表达式等),它会在 Future 对象完成后被调用。
      • wait_for():该函数用于等待异步操作的完成,但最多等待一定的时间。如果在指定的时间内异步操作未完成,则函数返回,并可以根据返回值判断异步操作的状态。
      • wait_until():该函数用于等待异步操作的完成,直到指定的时间点。如果在指定的时间点前异步操作未完成,则函数返回,并可以根据返回值判断异步操作的状态。
    • Future和CompletableFuture的区别
      • 阻塞性:Future在执行结束后无法回调,调用get方法会被阻塞。而CompletableFuture在调用get方法获取结果时也会被阻塞,但同时它还可以通过回调函数获取结果
      • 回调处理:Future模式执行批量任务,在完成任务后要想执行其他任务需要通过get方法获取结果,且各个get方法依赖于Future列表顺序。而CompletableFuture可以通过回调得到执行结果,各自完成任务后可以立即执行接下来的任务。
      • 任务组合:通过实现CompletionStage接口,CompletableFuture对象可以级联地执行任务。与Future相比,CompletableFuture的优势在于可以直接对多个任务进行链式、组合等处理,而不需要借助并发工具类。
      • 异步执行:CompletableFuture允许任务在后台线程中异步执行,不会阻塞主线程,提高了应用程序的响应性和性能。
    • CompletableFuture常用函数
      • CompletableFuture.supplyAsync(Supplier supplier): 异步地计算一个值(如Mapper层返回一个结果)
      • CompletableFuture.runAsync(Runnable runnable): 异步地执行一个操作(如Service执行一个过程)
      • CompletableFuture.allOf(CompletableFuture<?>… cfs): 等待一组 CompletableFuture 全部完成。
        • 使用工作窃取案例:
        ​​​​​​​CompletableFuture<List<?>> future = CompletabbleFuture. supplyAsync(() -> mapper.getList());
        
        //等待CompletableFuture对象都执行完成
        CompletableFuture. all0f(future).join();
        
        
        List<?> List=future.get();
        
      • get(): 获取异步计算的结果
      • 使用默认线程池和自定义线程池案例
        • public static CompletableFuture supplyAsync(Supplier supplier)
          // 带返回值异步请求,默认线程池
          • ForkJoinPool中有一个静态代码块,启动时会对commonParallelism进行初始化;根据CPU核心数来判断线程数量
            • 如果线程数量大于1
              • 创建一个基于工作窃取机制 的 ForkJoinPool(CPU密集型线程池)
                • 调用 ForkJoinPool.commonPool() 方法,可以获取到一个全局的 ForkJoinPool 实例,而无需手动创建和管理线程池。这样可以避免重复创建线程池的开销,提高代码的性能和可维护性
                • 默认大小通常等于处理器(CPU)核心的数量减一,主要用于处理那些可以进行分解的大型任务(即“分而治之”)
                • 性能受CPU的核心数量影响
              • 工作窃取算法
                • 一种优化多线程任务执行的策略,它的主要思想是让空闲的线程从其他忙碌的线程中窃取任务来执行。在ForkJoinPool中,当一个线程完成自己的任务后,它不会被动地等待,而是主动去寻找其他线程的双端队列中的任务来执行。这样做的好处是,即使某些线程已经完成任务而其他线程还在处理大量工作时,这些空闲线程也可以立刻投入工作,从而提高整体的工作效率
            • 如果线程数量小于等于1
              • JDK会创建一个ThreadPerTaskExecutor使用线程池,用一个线程去跑异步计算
          • 本机环境举例:CPU核心数是4核,线程数量就是3个
            • 函数内部,使用了2个CompletableFuture,不会有阻塞风险,当使用超3个以上,会执行完3个CompletableFuture的任务,此时会发生阻塞,等3个都执行完了,在往下执行其他的函数,阻塞时间为前面三个任务执行完成的耗时
          • 如果是我们系统开发优化:
            **举例:**前端页面所有的接口都是并发加载,查看有多少接口用了CompletableFuture.supplyAsync,总数量有没有超过核心线程数,进行相关统计后,在进行相关优化。
            • 如果线程数不够会 导致任务排队、响应延迟增加、资源竞争等问题,进而影响到系统的稳定性和性能。
          • 如果大部分接口中的Future.supplyAsync数量使用很多,超过了核心线程数,可以考虑用自定义线程,另外 ForkJoinPool 的特点是工作窃取算法,异步处理大型任务,将大型任务拆解多个子任务,高效处理。
        • public static CompletableFuture supplyAsync(Supplier supplier, Executor executor)
          // 带返回值的异步请求,可以自定义线程池
          自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数Python工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年Python开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。

img

img

img

img

img

img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上前端开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新

如果你觉得这些内容对你有帮助,可以扫码获取!!!(备注Python)

面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新**

如果你觉得这些内容对你有帮助,可以扫码获取!!!(备注Python)

img
  • 20
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值