有了 CompletableFuture,使得异步编程没有那么难了

本文介绍了在实现电视端专辑详情页改版需求时,如何利用CompletableFuture进行异步编程。通过Future的设计模式实战和CompletableFuture的模式实战,阐述了CompletableFuture的优势,如无需手动维护线程、代码简洁、支持链式调用等。此外,还给出了生产环境中的使用建议,如创建合理的线程池和异常处理,并进行了性能测试,证明了自定义线程池在高负载下的优势。
摘要由CSDN通过智能技术生成

本文导读:

  • 业务需求场景介绍
  • 技术设计方案思考
  • Future 设计模式实战
  • CompletableFuture 模式实战
  • CompletableFuture 生产建议
  • CompletableFuture 性能测试
  • CompletableFuture 使用扩展

1、业务需求场景介绍


不变的东西就是一直在变化中。

想必,大家在闲暇时刻,会经常看视频,经常用的几个 APP,比如优酷、爱奇艺、腾讯等。

这些视频 APP 不仅仅可以在手机上播放,还能够支持在电视上播放。

在电视终端上播放的 APP 是独立发布的版本,跟手机端的 APP 是不一样的。

当我们看一部电影时,点击进入某一部电影,就进入到了专辑详情页页面,此时,播放器会自动播放视频。用户在手机上看到的专辑详情页,与电视上看到的专辑详情页,页面样式设计上是不同的。

我们来直观的看一下效果。

手机上的腾讯视频专辑详情页:

有了 CompletableFuture,使得异步编程没有那么难了

 

上半部分截图,下面还有为你推荐、明星演员、周边推荐、评论等功能。

相应的,在电视端的专辑详情页展示方式是不一样的。假设产品经理提出一个需求,要求对详情页做个改版。

样式要求如下图所示:

有了 CompletableFuture,使得异步编程没有那么难了

 

两个终端的样式对比,在电视端专辑详情页中,包含了很多板块,每个板块横向展示多个内容。

产品的设计上要求是,有的板块内容来源于推荐、有的板块来源于搜索、有的板块来源CMS(内容管理系统)。简单理解为,每个板块内容来源不同,来源于推荐、搜索等接口的内容要求是近实时的请求。

2、技术设计方案思考


考虑到产品提的这个需求,其实实现起来并不难。

主要分为了静态数据部分和动态数据部分,对于不经常变化的数据可以通过静态接口获取,对于近乎实时的数据可以通过动态接口获取。

静态接口设计:

专辑本身的属性以及专辑下的视频数据,一般是不经常变化的。

在需求场景介绍中,我截图的是电影频道。如果是电视剧频道,会展示剧集列表(专辑下的所有视频,如第 1 集、第 2 集...),而视频的更新一般是不太频繁的,所以在专辑详情页剧集列表数据就可以从静态接口获取。

静态接口数据生成流程:

有了 CompletableFuture,使得异步编程没有那么难了

 

另外一部分,就是需要动态接口来实现,调用第三方接口获取数据,比如推荐、搜索数据。

同时,要求板块与板块之间的内容不允许重复。

动态接口设计:

方案一:

串行调用,即按照每个板块的展示先后顺序,调用相应的第三方接口获取数据。

方案二:

并行调用,即多个板块之间可以并行调用,提高整体接口响应效率。

其实以上两个方案,各有利弊。

方案一串行调用,好处是开发模型简单,按照串行方式依次调用接口,内容数据去重,聚合所有的数据返回给客户端。

但是,接口响应时间依赖于第三方接口的响应时间,通常第三方接口总是不可靠的,可能就会拉高接口整体响应时间,进而导致占用线程时间过长,影响接口整体吞吐量。

方案二并行调用,理论上是可以提高接口的整体响应时间,假设同时调用多个第三方接口,取决于最慢的接口响应时间。

并行调用时,需要考虑到「池化技术」,即不能无限制的在 JVM 进程上创建过多的线程。同时,也要考虑到板块与板块之间的内容数据,要按照产品设计上的先后顺序做去重。

根据这个需求场景,我们选择第二种方案来实现更合适一些。

选择了方案二,我们抽象出如下图所示的简易模型:

有了 CompletableFuture,使得异步编程没有那么难了

 

T1、T2、T3 表示多个板块内容线程。T1 线程先返回结果,T2 线程返回的结果不能与与 T1 线程返回的结果内容重复,T3 线程返回的结果不能与 T1、T2 两个线程返回的结果内容重复。

我们从技术实现上考量,当并行调用多个第三方接口时,需要获取接口的返回结果,首先想到的就是 Future ,能够实现异步获取任务结果。

另外,JDK8 提供了 CompletableFuture 易于使用的获取异步结果的工具类,解决了 Future 的一些使用上的痛点,以更优雅的方式实现组合式异步编程,同时也契合函数式编程。

3、Future 设计模式实战


Future 接口设计:

提供了获取任务结果、取消任务、判断任务状态接口。调用获取任务结果方法,在任务未完成情况下,会导致调用阻塞。

Future 接口提供的方法:

```

// 获取任务结果

V get() throws InterruptedException, ExecutionException;

// 支持超时时间的获取任务结果

V get(long timeout, TimeUnit unit)

throws InterruptedException, ExecutionExce

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值